Promise对象

本系列属于阮一峰老师所著的ECMAScript 6 入门学习笔记javascript


Promise的含义

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)
})
Promise.prototype.then()

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()

Promise.prototype.catch方式是.then(null,rejection)的别名,用于指定发生错误时的回调函数

getJSON('/posts.json').then(post=>{
  ...
}).catch(error =>{
  // 处理getJSON和前一个回调函数运行时发生的错误
  console.log('发生错误',error)
})
// Promise内部的错误不会影响Promise外部的代码
Promise.all()

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.race()方法一样是将多个Promise实例,包装成一个新的Promise实例

// 只要三个实例中有一个实例率先改变状态,p就会随着改变,率先改变的Promise实例的返回值就传递给p的回调函数
var p = Promise.race([p1,p2,p3])
Promise.resolve()

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()

promise.reject方法返回一个状态为rejected的新的Promise实例

//生成一个状态为rejected的实例
var p = Promise.reject('出错了')
p.then(null,function(s){
  console.log(s) // 出错了
})
//与Promise.resove方法不一样的是Promise.reject方法的参数会原封不动的变为后续方法的参数
done()
//由于Promise内部的错误不会冒泡到全局,done能够保证抛出任何可能出现的错误
asyncFunc().then(f1).catch(f2).then(f3).done()
finally()

finally用于指定无论Promse对象最后的状态如何,都会执行的操做。与done最大的不一样是接收一个普通的回调函数做为参数,该函数无论怎样都会执行

server.listen(0).then(()=>{}).finally(server.stop)
相关文章
相关标签/搜索