Node.js之Promise
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的更多相关文章
- Node.js之Promise维护(同步)多个回调(异步)状态
金天:学习一个新东西,就要持有拥抱的心态,如果固守在自己先前的概念体系,就会有举步维艰的感觉..NET程序员初用node.js最需要适应的就是异步开发, 全是异步,常规逻辑下遍历列表都是异步,如何保证 ...
- node.js的Promise库-bluebird示例
前两天公司一哥们写了一段node.js代码发给我,后面特意提了一句“写的不太优雅”.我知道,他意思是回调嵌套回调,因为当时比较急也就没有再纠结.然而内心中总记得要解决这个问题.解决node.js的回调 ...
- 在Node.js使用Promise的方式操作Mysql
最近在学习Node.js,虽然早就听说了回调地狱结果过了一周就遇到了.所以花时间学习了了一下Promise.虽然还有Async/await.co.生成器等选择,但是因为本人基础较差,以及时间问题所以决 ...
- 在Node.js使用Promise的方式操作Mysql(续)
在之后的开发中,为了做一些事务开发,我把mysql的连接代码从之前的query函数中分离出来了,直接使用原生的方法进行操作,但发现还是有点问题 原因是原生的node-mysql采用了回调函数的方式,同 ...
- when 让你跳出异步回调噩梦 node.js下promise/A规范的使用
其实关于promise 的博客,前端时间专门写了一篇关于 promise 规范的文章,promise规范 让 javascript 中的异步调用更加人性化. 简单回忆下: promise/A规范定义的 ...
- node.js的Promise对象的使用
Promise对象是干嘛用的? 将异步操作以同步操作的流程表达出来 一.Promise对象的定义 let flag = true; const hello = new Promise(function ...
- node.js使用汇总贴
金天:学习一个新东西,就要持有拥抱的心态,如果固守在自己先前的概念体系,就会有举步维艰的感觉..NET程序员初用node.js最需要适应的就是异步开发,以及弱类型语言难以避免的拼写错误与弱小的语法提示 ...
- Node.js用ES6原生Promise对异步函数进行封装
Promise的概念 Promise 对象用于异步(asynchronous)计算..一个Promise对象代表着一个还未完成,但预期将来会完成的操作. Promise的几种状态: pending:初 ...
- [Node.js] Promise,Q及Async
原文地址:http://www.moye.me/2014/12/27/promise_q_async/ 引子 在使用Node/JS编程的时候,经常会遇到这样的问题:有一连串的异步方法,需要按顺序执行, ...
随机推荐
- SharePoint 2013 中的SQL Server 安全
使用SharePoint很长时间以来,都认为Sql只需要最初始的配置,即不再需要管理和维护:而事实上,Sql的管理和安全,都是和SharePoint环境的稳定性息息相关的,所以,要绝对重视ShareP ...
- Force.com微信开发系列(八)生成带参数的二维码
为了满足用户渠道推广分析的需要,公众平台提供了生成带二维码的接口.使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送.目前有两种类型的二维码,分别是临时二维码和永久二维码 ...
- 安装sql server managerment studio报错"The instance id is required but it is missing"
问题描述: 今天在安装sql server managerment studio的时候提示报错"The instance id is required but it is missing&q ...
- String.format() 格式化字符串
1.几种常见的转换符 转换符 说明 实例 %d 整数类型(十进制) 99 %f 浮点类型 99.99 %s 字符串类型 "mingrisoft" %c 字符类型 'm' %b 布尔 ...
- iOS之 PJSIP静态库编译(一)
首先放上pjsip官方网站http://www.pjsip.org/download.htm 下载的时候注意while the .bz2 has LF line-ends and is for Uni ...
- js 毫秒 转 时间 日期 yyyy-mm-dd hh-mm-ss
//格式化时间 var format = function(time, format){ var t = new Date(time); var tf = function(i){return (i ...
- 一步步学敏捷开发:4、Scrum的3种角色
在Scrum角色中包括:产品负责人(Product Owner,PO).ScrumMaster(SM).开发团队(Team). 角色:产品负责人(PO) Scrum团队只有一个产品负责人,他负责在限定 ...
- iOS 应用架构浅谈
当我们讨论客户端应用架构的时候,我们在讨论什么? 其实市面上大部分应用不外乎就是颠过来倒过去地做以下这些事情: 简单来说就是调API,展示页面,然后跳转到别的地方再调API,再展示页面. App确实就 ...
- dd 生成指定大小文件
d命令可以轻易实现创建指定大小的文件,如 dd if=/dev/zero of=test bs=1M count=1000 会生成一个1000M的test文件,文件内容为全0(因从/dev/zero中 ...
- SQL SERVER 2012 使用订阅发布同步数据库
软件做大了,客户就多了,一个数据库服务器是远远不够的,当有一台数据服务器卦掉,那整个系统就会崩溃,所以必须考虑到数据库的自动同步与备份,当一台数据库服务 器宕机,自然就有用一台数据服务器启动起来保证整 ...