Promise

简介

Promise是一个异步编程的解决方案,此对象表示一个异步操作的最终状态(完成或失败),以及其返回的值。

Promise一共有三个状态:pending - 运行时,resolve - 成功,reject - 失败。当Promise的状态又pending转变为resolvedrejected时,会执行相应的方法,并且状态一旦改变,就无法再次改变状态,这也是它名字promise - 承诺的由来

链式调用是它的特点,好处在于统一执行ajax的逻辑,先不管如何处理结果,然后根据结果的成功和失败来决定调用success还是fail函数。

它的优点是链式调用,让代码更加简洁,脱离回调地狱,但是同时也是缺点,链式调用的隔层传参十分麻烦。

API

先看一个例子:

'use strict'
function test(resolve, reject) {
    // 生成一个随机数
    let sum = Math.random() * 2;
    console.log(sum);
    setTimeout(() => {
        if (sum < 1) {
            console.log('resolve...')
            resolve('200'); // pending ->> resolved
        } else {
            console.log('reject...')
            reject('500'); // pending ->> rejected
        }
    }, sum * 1000)
}
new Promise(test).then(function (result) {
    console.log('成功:' + result);
}).catch(function (reason, message) {
    console.log('失败:' + reason);
});

构造方法里放需要执行的异步函数,此函数接收两个参数:resolvereject,也就是成功或者失败,这是Promise的两个状态,还有一个是panding正在执行。

then

then()是异步调用函数执行之后要执行的操作,接收两个参数,分别是执行成功的参数和执行失败的参数(都是函数形式),但是一般不这么写,只用then()写执行成功后的函数操作,把失败后的操作交给catch()执行。

成功函数是上一个执行的函数的返回参数,并且then()也会返回一个全新的Prosime用来实现链式调用,基本上,每一个promise代表了链式中另一个异步过程的完成。

catch

此方法用来捕获在异步函数执行过程中发生的异常,也可以说失败后需要执行的业务逻辑,在这个方法后面如果还有then()的话会继续执行。

new Promise((resolve, reject) => {
    console.log('Initial');
    resolve(); // Promise状态由运行时转为失败
})
    .then(() => {
        throw new Error('Something failed'); // 异常的发生
        console.log('Do this');
    })
    .then(() => {
        console.log('Do'); // 不会执行
    })
    .then(() => {
        console.log('Do'); // 不会执行
    })
    .catch(() => {
        console.log('Do that'); // 执行
    })
    .then(() => {
        console.log('Do this whatever happened before'); // 执行
    });

all

除了执行若干个异步任务之外,还可以并发执行异步任务。

var p1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
    console.log(results); // 获得一个Array: ['P1', 'P2']
});

执行完毕后,会把all()中参数返回的结果收集到一个数组里传给下一个执行函数

race

这个函数是为了容错,跟all()一样接受一个数组,但是它只需要第一个最先执行完毕的函数的结果:

let p = new Promise((resolve, reject) => {
    resolve('200');
});
let p2 = new Promise((resolve, reject) => {
    reject('500');
});
Promise.race([p, p2]).then(function (result) {
    console.log(result) // 200
})

这么做是为了容错,只要参数数组中有一个状态改变了,promise就会立刻变成相同的状态并执行对于的回调

done

作用和then()相似,参数可有可无,不同的是它主要作用在于**捕捉在回调练底端catch没有捕捉到的异常

finally

Promise.finally() 接受一个方法作为参数,这个方法不管promise最终的状态是怎样,都一定会被执行

其他API

Promise.resolve()/Promise.reject()

用来包装一个现有对象,将其转变为Promise对象,但是Promise.resolve()会根据情况的不同返回不同的Promise

  • 参数就是Promise,那么原样返回。
  • 参数带有then(),将其转变为Promise之后立即执行then()
  • 参数不带then方法、不是对象或没有参数,返回resolved状态的Promise

Promise.reject()会直接返回rejected状态的Promise

Last modification:February 20th, 2018 at 10:12 am
If you think my article is useful to you, please feel free to appreciate

Leave a Comment