2015年发布了ES6标准,所谓 Promise,就是ES6标准的一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。

有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供统一的接口,使得控制异步操作更加容易。
var promise = new Promise(function(resolve, reject) {
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});

promise.then(function(value) {
// success
}, function(value) {
// failure
});
Promise函数接受一个函数作为参数,该函数的两个参数分别是 resolve 方法和 reject 方法。
如果异步操作成功,则用 resolve 方法将 Promise 对象的状态,从「未完成」变为「成功」(即从 pending 变为 resolved);

如果异步操作失败,则用 reject 方法将 Promise 对象的状态,从「未完成」变为「失败」(即从 pending 变为 rejected)。

小范例:

<!DOCTYPE>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>promise animation</title>
<style type="text/css">
.ball{
width: 40px;
height:40px;
border-radius: 20px;
}
.ball1{
background-color: red;
}
.ball2{
background-color: yellow;
}
.ball3{
background-color: green;
}
</style>
<script src="node_modules/bluebird/js/browser/bluebird.js"></script>
</head>
<body>
<div class="ball ball1" style="margin-left:0;"></div>
<div class="ball ball2" style="margin-left:0;"></div>
<div class="ball ball3" style="margin-left:0;"></div>
<script type="text/javascript">
var ball1=document.querySelector('.ball1');
var ball2=document.querySelector('.ball2');
var ball3=document.querySelector('.ball3'); function animate(ball,distance,cb){
setTimeout(function(){
var marginLeft=parseInt(ball.style.marginLeft,10);
if(marginLeft===distance){
cb&&cb();
}else{
if(marginLeft<distance){marginLeft++;}
else{marginLeft--;}
ball.style.marginLeft=marginLeft;
animate(ball,distance,cb);
//不断重复做这件事知道球移动到我们期望的位置
} },13)
} // animate(ball1,100,function(){
// animate(ball2,200,function(){
// animate(ball3,300,function(){
// animate(ball3,150,function(){
// animate(ball2,150,function(){
// animate(ball1,150,function(){ // })
// })
// })
// })
// })
// }) var Promise=window.Promise; function promiseAnimate(ball,distance){
return new Promise(function(resolve,reject){
function _animate(){
setTimeout(function(){
var marginLeft=parseInt(ball.style.marginLeft,10)
if(marginLeft===distance){
resolve()
}else{
if(marginLeft<distance){
marginLeft++
}else{
marginLeft--
}
ball.style.marginLeft=marginLeft+'px'
_animate()
}
},13)
}
_animate()
})
} promiseAnimate(ball1,100)
.then(function(){
return promiseAnimate(ball2,200)
})
.then(function(){
return promiseAnimate(ball3,300)
})
.then(function(){
return promiseAnimate(ball3,150)
})
.then(function(){
return promiseAnimate(ball2,150)
})
.then(function(){
return promiseAnimate(ball1,150)
}) </script>
</body>
</html>

关于Promise需要学习以下几点:

Promise的三种状态:

示例二,网络小爬虫

var http=require('http')
var cheerio=require('cheerio')
var baseUrl='http://www.imooc.com/learn/'
var videoIds=[348,259,197,134,75]
//var url='http://119.29.109.156:8080/ServerTest01/'
//each 和 forEach区别在于each可以改变数组中的数据
function filterChapters(html){
var $=cheerio.load(html)
var chapters=$('.chapter')
var title=$('.hd .l').text()
var number=parseInt($($('.meta-value strong')[3]).text().trim(),10)
/*courseData={
title:title,
number:number,
videos:
[{ chapterTitle:''
videos:[ title:'' id:'' ]
}] }*/
var courseData={
videos:[],
number:number,
title:title
}
//将课程名和学习人数进行写入
courseData.title=title
courseData.number=number
chapters.each(function(item){
var chapter=$(this)
var chapterTitle=chapter.find('strong').text()
var videos=chapter.find('.video').children('li')
var chapterData={ chapterTitle:chapterTitle, videos:[] }
videos.each(function(item){
var video=$(this).find('.studyvideo')
var videoTitle=video.text()
var videoid=video.attr('href').split('video/')[1]
chapterData.videos.push({ title:videoTitle, id:videoid })
})
courseData.videos.push(chapterData)
})
return courseData
} function printCourseInfo (coursesData) {
console.log('printCourseInfo')
coursesData.forEach(function(courseData){
console.log(courseData.number+' 人学过 '+courseData.title+'\n')
})
coursesData.forEach(function(courseData){
console.log('### '+courseData.title+'\n')
courseData.videos.forEach(function(item){
var chapterTitle=item.chapterTitle
console.log(chapterTitle+'\n')
item.videos.forEach(function(video){
console.log(' ['+video.id+'] '+video.title+'\n')
})
})
})
} function getPageAsync(url){
return new Promise(function(resolve,reject){
console.log('正在爬取 '+url)
http.get(url,function(res){
var html=''
res.on('data',function(data){
html += data
})
res.on('end',function(){
console.log('爬取 '+ url+' 成功')
resolve(html)
})
}).on('error',function(e){
reject(e)
console.log('获取课程数据出错')
})
})
}
//存放所有课程的html的一个数组
var fentchCourseArray=[]
videoIds.forEach(function(id){
fentchCourseArray.push(getPageAsync(baseUrl+id))
}) Promise
.all(fentchCourseArray)
.then(function(pages){
var coursesData=[]
pages.forEach(function(html){
console.log("1111")
var courses=filterChapters(html)
coursesData.push(courses)
})
coursesData.sort(function(a,b){
return a.number<b.number
})
printCourseInfo(coursesData)
})

Node.js之Promise的更多相关文章

  1. Node.js之Promise维护(同步)多个回调(异步)状态

    金天:学习一个新东西,就要持有拥抱的心态,如果固守在自己先前的概念体系,就会有举步维艰的感觉..NET程序员初用node.js最需要适应的就是异步开发, 全是异步,常规逻辑下遍历列表都是异步,如何保证 ...

  2. node.js的Promise库-bluebird示例

    前两天公司一哥们写了一段node.js代码发给我,后面特意提了一句“写的不太优雅”.我知道,他意思是回调嵌套回调,因为当时比较急也就没有再纠结.然而内心中总记得要解决这个问题.解决node.js的回调 ...

  3. 在Node.js使用Promise的方式操作Mysql

    最近在学习Node.js,虽然早就听说了回调地狱结果过了一周就遇到了.所以花时间学习了了一下Promise.虽然还有Async/await.co.生成器等选择,但是因为本人基础较差,以及时间问题所以决 ...

  4. 在Node.js使用Promise的方式操作Mysql(续)

    在之后的开发中,为了做一些事务开发,我把mysql的连接代码从之前的query函数中分离出来了,直接使用原生的方法进行操作,但发现还是有点问题 原因是原生的node-mysql采用了回调函数的方式,同 ...

  5. when 让你跳出异步回调噩梦 node.js下promise/A规范的使用

    其实关于promise 的博客,前端时间专门写了一篇关于 promise 规范的文章,promise规范 让 javascript 中的异步调用更加人性化. 简单回忆下: promise/A规范定义的 ...

  6. node.js的Promise对象的使用

    Promise对象是干嘛用的? 将异步操作以同步操作的流程表达出来 一.Promise对象的定义 let flag = true; const hello = new Promise(function ...

  7. node.js使用汇总贴

    金天:学习一个新东西,就要持有拥抱的心态,如果固守在自己先前的概念体系,就会有举步维艰的感觉..NET程序员初用node.js最需要适应的就是异步开发,以及弱类型语言难以避免的拼写错误与弱小的语法提示 ...

  8. Node.js用ES6原生Promise对异步函数进行封装

    Promise的概念 Promise 对象用于异步(asynchronous)计算..一个Promise对象代表着一个还未完成,但预期将来会完成的操作. Promise的几种状态: pending:初 ...

  9. [Node.js] Promise,Q及Async

    原文地址:http://www.moye.me/2014/12/27/promise_q_async/ 引子 在使用Node/JS编程的时候,经常会遇到这样的问题:有一连串的异步方法,需要按顺序执行, ...

随机推荐

  1. android 开源和一些博客总结

    记录一些开源的android库 (1)Http请求库封装 https://github.com/kevinsawicki/http-request (2)浮动组件,定制化 toast http://f ...

  2. [leetcode] Reverse Bits

    Reverse Bits Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (re ...

  3. Spring(一)简述

    一.Spring简述 一段费话 Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2 ...

  4. oc语言常用的字符串函数

    #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { ...

  5. iOS 编译报错

    Undefined symbols for architecture i386: “_OBJC_CLASS_$_XXX”, referenced from: objc-class-ref in XXX ...

  6. C++语言-04-重载

    相关概念 重载 在同一作用域中为某个函数和运算符指定多个定义,分别成为函数重载和运算符重载 重载声明 与之前已经在作用域内声明过的函数或方法具有相同名称的声明,参数列表和定义不同 重载决策 调用一个重 ...

  7. IOS之未解问题--给UITableView提取UITableViewDataSource并封装瘦身失败

    前言:阅读了<更轻量的 View Controllers>,发现笔者这个优化重构代码的想法真的很不错,可以使得抽取的UITableViewDataSource独立写在一个类文件里,并且也写 ...

  8. [QualityCenter]设置工作流脚本-设置不同字段值关联不同列表

    需求:当选择A字段某个值时,设置B字段的列表值根据A字段的值来判断读取不同的列表值,如当运行省份的值已更改, 运行地区的选择列表将更改. 在脚本编辑器新建一个函数UserFuntion_Bug_Pro ...

  9. Erlang 虚拟机 BEAM 指令集之内存管理相关的指令

    翻看 BEAM 虚拟机指令集的时候(在编译器源码目录下:lib/compiler/src/genop.tab),会发现有一些和内存分配/解除分配相关的指令,如下所示: allocate StackNe ...

  10. RESTful API的设计与开发

    自己做过关于RESTful API的培训,下载