此博客不再维护,博客已迁移至 https://github.com/purplebamboo/blog/issues
文章目录
  1. 1. 规范里的定义
  2. 2. promise对象的then方法
  3. 3. promise对象的catch方法
  4. 4. Promise的类方法resolve和reject
  5. 5. Promise的类方法all和race
  6. 6. Promise的类方法defer使用

promise最早是在commonjs社区提出来的,当时提出了很多规范。比较接受的是promise/A规范。后来人们在这个基础上。提出了promise/A+规范,也就是实际上的业内推行的规范。es6也是采用的这种规范。

promise/A规范在这里

promise/A+规范在这里还有中文版

不过规范这种东西看着比较晦涩。下面具体说说promise的用法。

规范里的定义

什么是promise呢,说白了就是一个承诺,我承诺你叫我做的事情我将来会去做,不过要等我能去做的时候。

一个promise对象有三种状态,预备状态(pending),成功态(fulfilled),失败态(rejected)。

我们看下promise对象的构造函数:

1
2
3
4
5
6
7
8
9
10
11
var promise = new Promise(function(resolve, reject) {
    //if(报错){
        //reject(new Error('promise出错啦。。'))
    //}

    //某个异步操作,比如ajax请求
    setTimeout(function(){
        resolve('异步请求结束了。。变成完成态')
    },1000)

});

promise对象初始状态一般是预备状态,并且promise对象的状态转换只能是预备状态到成功态或者预备状态到失败态。

  • resolve会将promise转变为成功态。
  • reject会将promise转变为失败态。

promise对象的then方法

我们可以使用promise对象的then方法往这个对象里面添加回调函数。调用方式为:

1
promise.then(onFulfilled, onRejected)

then接受一个成功回调,还有失败回调。都是可选参数。
当promise对象是预备状态这些函数不会立即执行。而是等待。
当promise对象变成了成功态会调用onFulfilled,参数为resolve传递的值。
变成失败态则会调用onRejected,参数为reject传递的值。

因为then返回一个promise对象。所以支持链式调用:

1
promise.then(onFulfilled, onRejected).then(onFulfilled, onRejected)

then负责往promise对象里添加函数,随便添加多少。

  • 如果promise对象处于预备状态就等待。一直到改变状态才开始执行。
  • 如果promise对象已经处于结束态(成功或者失败)再用then添加回调就直接调用对应的回调。
  • 此外前一个onFulfilled函数的返回值如果不是promise。会作为下一个onFulfilled的参数。onRejected类似。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//onRejected可以为null也可以省略
promise.then(function(prevValue){

    console.log('resolve的值:'+prevValue)

    return "我是传递给第二个回调的参数"
},null).then(function(value){
    console.log('报告:'+ value)
    console.log('我是最后一个')
})

/*
*结果
resolve的值:异步请求结束了。。变成完成态
报告:我是传递给第二个回调的参数
我是最后一个
*/

可以看到一直等到前面的异步操作结束了,后面的才会执行。

此外如果onFulfilled返回一个新的promise对象,那么之后的then添加的操作函数会被托管给新的promise对象。然后之后的操作函数执不执行就由新的promise对象说了算了。

比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
promise.then(function(prevValue){

    console.log('resolve的值:'+prevValue)

    var newPromise =  new Promise(function(resolve,reject){
         setTimeout(function(){
            resolve('2秒后,新的promise变成完成态')
         },2000)

    })
    //返回新的promise
    console.log('返回一个promise,开始托管。')
    return newPromise

},null).then(function(value){
    console.log('报告:'+ value)
    console.log('我是最后一个')
})
/*
*结果
resolve的值:异步请求结束了。。变成完成态
返回一个promise,开始托管。
报告:2秒后,新的promise变成完成态
我是最后一个
*/

promise对象的catch方法

用来捕获上一个then方法里面reject过来的错误,说白了就是一种特殊的then

1
2
3
4
5
6
7
8
9
promise.catch(function(error) {
  console.log('发生错误!', error);
});

//等价于

promise.then(null,function(error) {
  console.log('发生错误!', error);
});

Promise的类方法resolve和reject

Promise.resolve
接受的参数如果是promise对象就直接返回。
如果是一个非promise,但具有then方法的对象就会尝试转换成一个成功状态的promise对象。
如果是个不具有then方法的值就传递给下一个onFulfilled函数,并且生成一个处于成功状态的promise对象。

Promise.reject
接受的参数如果是promise对象就直接返回。
如果是一个非promise,但具有then方法的对象就会尝试转换成一个失败状态的promise对象。
如果是个不具有then方法的值就传递给下一个onRejected函数。并且生成一个处于失败状态的promise对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var a = Promise.resolve(true)
//same as
var a = new Promise(function(resolve,reject){
    //立即变成成功状态
    resolve(true)
})

var b = Promise.reject(true)
//same as
var b = new Promise(function(resolve,reject){
    //立即变成失败状态
    reject(true)
})


//使用Promise.resolve转换不标准的jQuery的promise对象
var promise = Promise.resolve($.get('http://www.taobao.com'));

Promise的类方法all和race

Promise.all用来包装一系列的promise对象返回一个包装后的promise对象,比如我们称之为A。

  • 当所有的promise对象都变成成功状态(fulfilled)后。这个包装后的A才会把自己变成成功态。A会等最慢的那个promise对象变成成功态(fulfilled)后把自己变成成功态。
  • 只要其中一个promise对象变成失败态(rejected),包装后的A就变成rejected,并且第一个rejected传递的值,会传递给A后面使用then添加的onRejected回调。
1
2
3
4
var a = new Promise(function(resolve,reject){})
var b = Promise.resolve(true)

Promise.all([a,b])

Promise.race也是用来包装一系列的promise对象返回一个包装后的promise对象,比如我们称之为B。跟all不同的是,只要有一个对象变成了成功状态(fulfilled),B就会变成成功状态。

1
Promise.race([a,b])

all是一种与的关系,而race是一种或的关系。

Promise的类方法defer使用

其实除了在构造函数里面使用resolve,reject去改变一个promise对象的状态外,我们还有另外一种方式。那就是defer。
例子:

1
2
3
4
5
6
7
8
9
10
promise.then(function(val){

    var d = Promise.defer()
    setTimeout(function(){
        d.resolve('2秒后,新的promise变成完成态')
        //d.reject('err')
    },2000)
    //返回自己的promise对象
    return d.promise
})

Promise.defer()生成一个defer对象。这个对象d具有一个promise对象属性。d.resolve会把管理的promise变成完成态,同理d.reject会将管理的promise变成失败态。

整个promise的用法就说完了。

其实A+规范中只定义了then函数的具体细节,而promise状态的改变都是前人的经验慢慢积累后总结出的一套使用方式

参考链接:

  1. http://www.w3ctech.com/topic/721
  2. http://www.cnblogs.com/fsjohnhuang/p/4135149.html
  3. http://wohugb.gitbooks.io/ecmascript-6/content/docs/promise.html
文章目录
  1. 1. 规范里的定义
  2. 2. promise对象的then方法
  3. 3. promise对象的catch方法
  4. 4. Promise的类方法resolve和reject
  5. 5. Promise的类方法all和race
  6. 6. Promise的类方法defer使用