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. AsyncTask.cancel()的结束问题

    实际项目中有这么一个问题,用户进入详情界面,那么我们就要网络加载数据并展现在UI上,这个加载用线程或者异步. 这里就拿项目中统一用异步任务来获取网络数据把. 用户可能会有这么一个操作,它在一个商品(说 ...

  2. iOS 视频播放 - YVideoPlayer - UIView

    这是一个使用简便的视频播放框架,它基于UIView,它可以是一个小窗口,也可以是一个全屏的窗口 简单的方式加载Video框架: 一行代码加载! 一行代码更新! 下载链接 : https://githu ...

  3. [leetcode] Count Primes

    Count Primes Description: Count the number of prime numbers less than a non-negative number, n click ...

  4. 如何发布得到.ipa文件

    第一个方法: 如果都有证书的话,并且又不想把别人的机器添加到测试设备中,或者感觉获取UDID麻烦的话,那么就可以采用该方法了. 直接Archive应用程序: 右键显示包内容到product下复制里面的 ...

  5. C语言-08-预处理器

    C预处理器,C Preprocessor简称CPP.C预处理器不是编译器的一部分,它是一个单独的文本替换工具,指示编译器在实际编译之前需要完成的工作. 常用的预处理器指令 #include 包含头文件 ...

  6. UIWebView的基本用法

    一.UIWebView的基础使用 1.创建UIWebView: CGRect bouds = [[UIScreen manScreen]applicationFrame]; UIWebView* we ...

  7. 打印 SpringMVC中所有的接口URL

    采用junit test方式 1.配置  simple-test.xml  <?xml version="1.0" encoding="UTF-8"?&g ...

  8. Apache Shiro 简介

    使用 Apache Shiro 为 web 应用程序进行用户身份验证 Shiro 是一个 Apache Incubator 项目,旨在简化身份验证和授权.在本文中,了解 Apache Shiro 并通 ...

  9. Scrum不是万能药,要在时机成熟时推行

    敏捷很火热,大家都在谈敏捷:但不是所有团队都适合敏捷! 需要等待时机,时机成熟了,才推! 什么时候算时机成熟呢? 我们的经验是需要两点: 一.团队有三名或以上的研发工程师 : 二. 团队内有一名合适的 ...

  10. nim3取石子游戏 (威佐夫博弈)

    http://www.cnblogs.com/jackge/archive/2013/04/22/3034968.html 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有 ...