Promise

200 阅读3分钟

1、什么是Promise?

Promise是一个对象,保存着异步操作的结果(通常是异步操作,也可以是同步操作),异步操作结束后,会变更其状态,然后调用注册在then方法上的回调函数。

从图中可以看到Promise构造函数的原型上分别挂载了thencatchfinally方法

2、先看简单的用法

let promise = new Promise((resolve, reject) => {
    let a = Math.random()
    setTimeout(() => {
        if (a > 0.5) {
            resolve('success')
        } else {
            reject('error')
        }
    }, 1000)
})

promise.then(res => {
    console.log(res)
}).catch(err => {
    console.log(err)
})

如果随机数a大于0.5将会调用绑定在then方法上的回调函数,并且打印出success,反之则打印出error

3、Promise的状态

Promise有三种状态:

  • pending: 初始状态,既不是成功,也不是失败状态。
  • fulfilled: 意味着操作成功完成。
  • rejected: 意味着操作失败。

pending状态的promise可能会触发fulfilled状态或者rejected状态,并传入一个值给then方法,then方法包含了两个参数(onfulfilled和onrejected),fulfilled状态会调用onfulfilled方法,rejected状态onrejected方法,即下面所示:

promise.then(function onfulfilled (res) {
    console.log(res)
},function onrejected (err){
    console.log(err)
})

从第一张图可以看到,then方法是定义在Promise的原型上的,原型上同时有catch方法,catch方法是 Promise.prototype.then(null, onrejected)或者Promise.prototype.then(undefined, onrejected)的别名

一般我们会才去catch方法来捕捉rejected状态,这是因为onfulfilled如果有错误会被catch所捕捉到。

/ bad
promise.then(function(res) {
    // success
}, function(err) {
    // error
 });

// good
promise.then(function(res) {
    // success
}).catch(function(err) {
    // error
});

3、new Promise的快捷方式

Promise.resolve(error) 是和 Promise.reject(value) 类似的静态方法,是 new Promise() 方 法的快捷方式。

Promise.resolve(42)
// 可以认为是下面的语法糖
new Promise(function(resolve){ 
    resolve(42)
});

Promise.reject(new Error("出错了")) 
// 可以认为是下面的语法糖
new Promise(function(resolve,reject){ 
    reject(new Error("出错了"))
})

4、Promise链式调用

从图中可以看到then方法可以链式调用,也就是在then方法后面可以接着写then方法,这是因为then方法返回的是一个新的Promise实例,

那如何在then方法之间传值呢,就是第一个then方法的值能够传递给第二个then方法,以此类推,答案非常简单,就是在then方法中return相应值就可以了

function doubleValue(value) { 
    return value * 2
}

function increment(value) {
    return value + 1
}
function output(value) { 
    console.log(value) // => (1 + 1) * 2
}
var promise = Promise.resolve(1); 
promise
    .then(increment) 
    .then(doubleValue) 
    .then(output) 
    .catch(function(error){
        // promise chain中出现异常的时候会被调用
        console.error(error)
    });

整体流程:

  1. Promise.resolve(1); 传递 1 给 increment 函数
  2. 函数 increment 对接收的参数进行 +1 操作并返回(通过 return )
  3. 这时参数变为2,并再次传给 doubleValue 函数
  4. 最后在函数 output 中打印结果

5、Promise.all

Promise.all 接收一个 promise对象的数组作为参数,当这个数组里的所有promise对象 全部变为fulfilledrejected状态的时候,它才会去调用 .then 方法。

6、Promise.race

Promise.all相对, Promise.race是只要有一个promise对象进入 fulfilled 或者 rejected 状态的话,就会继续进行后面的处理。

如上整理,有误请指正。