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编程的时候,经常会遇到这样的问题:有一连串的异步方法,需要按顺序执行, ...
随机推荐
- Installing FIM 2010 R2 SP1 Portal on SharePoint Foundation 2013
http://www.fimspecialist.com/fim-portal/installing-fim-2010-r2-sp1-portal-on-sharepoint-foundation-2 ...
- vc6.0连接mysql数据库
一.MySQL的安装 Mysql的安装去官网下载就可以...最新的是5.7版本.. 二.VC6.0的设置 (1)打开VC6.中选0 工具栏Tools菜单下的Options选项,在Directories ...
- Struts2(十四)拦截器实现权限管理
一.认识拦截器 拦截器也是一个类 拦截器可以在Action被调用之前和之后执行代码 框架很多核心功能是拦截器实现的 拦截器的特点: 拦截器自由组合,增强了灵活性.扩展性.有利于系统解耦 拦截器可以拦截 ...
- UI界面的一些简单控件
虽然都是代码 , 但是基本都有注释. #import "ViewController.h" @interface ViewController () /** * 创建视图 */ @ ...
- android 音乐播放器简单实现
package com.zhangbz.musicplayer; import java.io.File; import android.app.Activity; import android.me ...
- 使用culr
使用curl在采集有语言要求的网站时,首先需要发送带有语言设置的请求,再发送你要的请求如: 注:vget(); 这里没提供: $url='http://www.hotels.com/?locale=e ...
- mybatis java.lang.UnsupportedOperationException
mybatis抛出下面的异常: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exc ...
- Java文件IO操作应该抛弃File拥抱Paths和Files
Java7中文件IO发生了很大的变化,专门引入了很多新的类: import java.nio.file.DirectoryStream;import java.nio.file.FileSystem; ...
- MemSQL分布式架构介绍(二)
接上次的MemSQL分布式架构介绍(一),原文在这里:http://docs.memsql.com/latest/concepts/distributed_architecture/ 首先上张图,是我 ...
- 问题解决——VS2010 将生成的文件复制到指定位置
我是从VC6直接过渡到VS2010的,VS2008没怎么用过.用VS2010的时候,每次生成dll后,手工把dll.lib..h文件复制到指定文件夹太麻烦了,所以着手写了这个. =========== ...