概念
Promise
对象用于表示一个异步操作的最终完成 (或失败), 及其结果值.让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise
对象.
Promise
的三种状态分别为:
pending
: 初始状态,既不是成功,也不是失败状态。fulfilled
: 意味着操作成功完成。rejected
: 意味着操作失败。
无论执行的结果是成功还是失败,Promise 对象的 then
方法绑定的处理方法就会被调用,then
有俩个为Function
类型的参数:
onfulfilled
:成功时调用onrejected
:失败时调用
而catch()
方法和then
失败调用时函数的作用相同,可以理解为其简写.
同时Promise.prototype.then
和 Promise.prototype.catch
方法返回promise
对象,所以它们可以被链式调用。
实例
function sayLove(){ new Promise(function (resolve, reject) { var love = Math.random() * 2 //随机生成 0 - 2 之间的随机数 setTimeout(function () { if (love > 1) { resolve('表白成功'); } else { reject('表白失败'); } }, love * 1000); }).then(function (result) { console.log(result +',进行下一步计划'); }).catch(function (reason) { console.log(reason+ ',总结原因,继续努力'); }); } sayLove()
catch
方法还有另一个作用,就是在执行resolve的回调时,如果抛出出错了,那么并不会报错卡死js,而是会进到这个catch
方法中。
function sayLove(){ new Promise(function (resolve, reject) { var love = Math.random() * 2 //随机生成 0 - 2 之间的随机数 setTimeout(function () { if (love > 1) { resolve('表白成功'); } else { reject('表白失败'); } }, love * 1000); }).then(function (result) { console.log(result +',进行下一步计划') console.log(plan);//plan 未定义 }).catch(function (reason) { console.log(reason+ ',总结原因,继续努力') }) } sayLove() //输出
方法
all()
all
方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。
简单来说就是等待速度最慢的人完成后一起回调,如果一人出错,全部完蛋.
const p = Promise.all([p1, p2, p3]);
- 只有
p1、p2、p3
的状态都变成fulfilled(成功)
,p
的状态才会变成fulfilled
,此时p1、p2、p3
的返回值组成一个数组,传递给p
的回调函数。 - 只要
p1、p2、p3
之中只要有一个被rejected(失败)
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p的回调函数。
function sayLove(id){ return new Promise(function (resolve, reject) { var love = Math.random() * 2 //随机生成 0 - 2 之间的随机数 setTimeout(function () { if (love > 0) {//这里改为 0,让所有测试通过 resolve(id+'表白成功'); } else { reject(id+'表白失败'); } }, love * 1000); }) } const promises = [2, 3, 5, 7, 11, 13].map(function (id) { return sayLove(id); }) Promise.all(promises).then(function (results) { console.log(results); }).catch(function(reason){ console.log(reason) }) //输出:["2表白成功", "3表白成功", "5表白成功", "7表白成功", "11表白成功", "13表白成功"] //若有一个失败,便会执行catch,例如:5表白失败
race()
race
方法是当任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。
就是谁跑得快,就执行谁.
function sayLove(id){ return new Promise(function (resolve, reject) { var love = Math.random() * 2 //随机生成 0 - 2 之间的随机数 setTimeout(function () { if (love > 1) {//这里改为 0,让所有测试通过 resolve(id+'表白成功'); } else { reject(id+'表白失败'); } }, id * 1000) //改变每个执行的时间 }).then(function (result) { console.log(result +',进行下一步计划') }).catch(function (reason) { console.log(reason+ ',总结原因,继续努力') }) } const promises = [2, 3, 5, 7, 11, 13].map(function (id) { return sayLove(id); }) Promise.race(promises).then(function (results) { console.log(results); }).catch(function(reason){ console.log(reason) }) //会先输出: 2表白成功,进行下一步计划 //然后陆续输出:3,5,7,11,13 的结果 // 若子 promise 对象没有 then 回调函数 // 那么只会输出 2表白成功
race
和 all
方法不同,谁的速度最快就执行谁,无论它是失败还是成功.所以通常会被用来给一个请求设定请求时间,如果超过限定时间,就返回失败.
const p = Promise.race([ fetch('/resource-that-may-take-a-while'), new Promise(function (resolve, reject) { setTimeout(() => reject(new Error('request timeout')), 5000) }) ]); p .then(console.log) .catch(console.error);
上面代码中,如果 5 秒之内fetch
方法无法返回结果,变量p的状态就会变为rejected
,从而触发catch
方法指定的回调函数。
allSettled()
该方法与 all
方法一样,会等待所以执行完成才回调返回一个数组,不同的是它不会在乎子 promise 是否成功.
any()
any()
只要参数实例有一个变成fulfilled
状态,包装实例就会变成fulfilled
状态;如果所有参数实例都变成rejected
状态,包装实例就会变成rejected
状态。
简单来说就是除非所有子 promise
都失败,否则就会返回成功.不过这个方法的返回值还未确定,该方法目前是一个第三阶段的提案 。
Promise.any()
跟Promise.race()
方法很像,只有一点不同,就是不会因为某个 Promise
变成rejected
状态而结束。
总结
then
: 通常执行成功回调catch
: 通常执行成功回调all
: 通常用于异步并发race
: 通常用于限定请求时间allSettled
: 不在乎子 promise 结果,全部返回any
: 还在提案阶段