本系列属于阮一峰老师所著的ECMAScript 6 入门学习笔记javascript
Promise是异步编程的一种解决方案。java
所谓Promise
,简单说是一个容器,里面保存这某个将来才会结束的事件的结果。es6
Promise
对象有如下两个特色:编程
1.对象的状态不受外部影响。Promise
对象表明一个异步操做,有三种状态:pending
(进行中)、fulfilled
(已成功)和rejected
(已失败)。只有异步操做的结果,能够决定当前是哪种状态,任何其余操做都没法改变这个状态。json
2.一旦状态改变,就不会再变,任什么时候候均可以获得这个结果。Promise
对象的状态改变,只有两种可能:从pending
变为fulfilled
和从pending
变为rejected
。只要这两种状况发生了,状态就凝固了,会一直保持这个结果,这时称为rejected
(已定型)。数组
var promise = new Promise(function(resolve,reject){ // ... some code if(/*异步操做成功*/){ resolve(value) }else{ reject(error) } })
resolve
函数的做用是将Promise
对象的状态从pending
变成resolved
,并将异步操做的结果做为参数传递出去。promise
reject
函数的做用是将Promise
对象的状态从pending
变成rejected
,在异步操做失败时调用,并将异步操做报出的错误,做为参数传递出去。异步
Promise
实例生成后,能够用then
方法分别指定resolved
状态和rejected
状态的回调函数async
function timeout(ms){ return new Promise((resolve,reject)=>{ setTimeout(reslove,ms,'done') }) } // Promise新建后就会当即执行 timeout(100).then(value=>{ console.log(value) })
then
的做用是为Promise实例添加状态改变时的回调函数,then
的第一个参数是resolved
状态的回调函数,第二个参数(可选)是rejected
状态的回调函数。异步编程
then
方法返回的是一个新的Promise
实例(注意,不是原来的那个Promise实例),所以能够采用链式写法
getJson('/posts.json').then(function(json){ return json.post }).then(function(post){ ... }) // 使用then的第一个回调函数若是仍是一个Promise对象,后一个回调函数,会等待Promise对象的状态发生改变才会被调用 getJson('/post/1.json').then( post=>getJson(post.commentURL) ).then( comments => console.log('resolved:',comments), err => console.log('rejected',err) )
Promise.prototype.catch
方式是.then(null,rejection)
的别名,用于指定发生错误时的回调函数
getJSON('/posts.json').then(post=>{ ... }).catch(error =>{ // 处理getJSON和前一个回调函数运行时发生的错误 console.log('发生错误',error) }) // Promise内部的错误不会影响Promise外部的代码
Promise.all
方法用于将多个Promise实例,包装成一个新的Promise实例
// 只有p一、p二、p3的状态都变为fulfilled,p的状态才会变成fulfilled,此时p一、p二、p3的返回值组成一个数组,传递给p的回调函数 //只要p一、p二、p3之中有一个被rejected,p的状态就变成rejected,此时第一个rejected实例的返回值会传递给p的回调函数 var p = Promise.all([p1,p2,p3]) //生成一个Promise对象的数组 var promises = [2,3,4,5,6,7,8].map(id=>{ return getJSON('/post'+id+'.json') }) Promise.all(promises).then(posts=>{ // ... }).catch(error=>{ // ... }) // 只有全部实例状态变为fulfilled或者其中一个变为rejected才会调用Promise.all方法后面的回调函数 // 若是做为参数的Promise实例本身定义了catch方法,那么它一旦被rejected,就不会触发Promise.all()的catch方法
Promise.race()
方法一样是将多个Promise实例,包装成一个新的Promise实例
// 只要三个实例中有一个实例率先改变状态,p就会随着改变,率先改变的Promise实例的返回值就传递给p的回调函数 var p = Promise.race([p1,p2,p3])
Promise.resolve
方法能够将现有对象转化为Promise对象
Promise.resolve('foo') // 等价于 new Promise(resolve=>resolve('foo'))
Promise.resolve
方法的参数分为四种状况
1.参数是一个Promise实例
Promise.resolve
不作任何修改、原封不动返回Promise实例
2.参数是一个thenable
对象
thenable
对象指的是具备then
方法的对象
let thenable = { then: function(resolve,reject){ resolve(40) } } let p1 = Promise.resolve(thenable) p1.then(function(value){ console.log(value) // 42 })
3.参数不是具备then
方法的对象,或根本就不是对象
var p = Promise.resolve('Hello') // 字符串不属于异步操做(判断方法是字符串对象不具备then方法),返回Promise一辈子成就是resolved,回调函数会当即执行,Promise.resove方法的参数会同时传给回调函数 p.then(function(s){ console.log(s) // Hello })
4.不带任何参数
var p = Promise.resolve() p.then(function(){ // ... }) setTimeout(function(){ console.log('three') },0) // 在下一轮事件循环开始时当即执行 Promise.resolve().then(function(){ console.log('two') }) //在本轮事件循环结束时执行 console.log('one') //当即执行
promise.reject
方法返回一个状态为rejected
的新的Promise实例
//生成一个状态为rejected的实例 var p = Promise.reject('出错了') p.then(null,function(s){ console.log(s) // 出错了 }) //与Promise.resove方法不一样的是Promise.reject方法的参数会原封不动的变为后续方法的参数
//由于Promise内部的错误不会冒泡到全局,done能够保证抛出任何可能出现的错误 asyncFunc().then(f1).catch(f2).then(f3).done()
finally
用于指定无论Promse对象最后的状态如何,都会执行的操做。与done
最大的不一样是接收一个普通的回调函数做为参数,该函数无论怎样都会执行
server.listen(0).then(()=>{}).finally(server.stop)