从这个单词语义上能够得知:这是一个承诺。承诺以一种优雅的方式处理咱们的异步操做的回调函数带来的一系列的问题(调用时序、异常捕获等)。目前基于promise实现的API与类库也是不少的,而且普遍被你们使用(fetch、axios、oss sdk等)。javascript
曾几什么时候,咱们在传统前端开发技术中,常用callback的方式来解决咱们在处理异步数据请求,当业务场景过于复杂时,常常就会写出callback中再callback的代码,也就是你们常说的又臭又长的回调地狱。使用咱们的promise方式处理,就能够优雅解决咱们的问题。前端
咱们能够在控制台打印一下咱们的Promise对象。能够看到Promise是一个构造函数,在它的原型上拥有then、catch、finally等方法,自身拥有all、race、reject、resolve等方法。java
ES6 中的 promise 实现是基于 Promises/A+ 规范。主要是对promise的状态、thenable对象、执行过程等进行规范。ios
等待中(Pending)
、执行成功(Fulfilled)
、执行失败(Rejected)
这三种中的一种。promsie状态 只能由 pending => fulfilled/rejected, 一旦修改就不能再变。onFulfilled
、onRejected
。这两个参数通常来讲都是函数,若是传入的不是函数将会被忽略。onFulfilled回调函数是在promise对象的状态变为resolved时调用,onRejected回调函数是在promise对象的状态变为rejected时调用。then方法赞成也必须返回一个promise对象,这样就造成了链式调用。静态方法git
Promise.resolve
返回一个fulfillled状态的promise对象。Promise.reject
返回一个rejected状态的promise对象。能够认为是new Promise()
的快捷方式。github
Promise.reslove('hahaha');
// 至关于
new Promise((relove, reject) => {
reslove('hahahha');
})
Promise.reject('hahaha');
// 至关于
new Promise((relove, reject) => {
reject('hahahha');
})
复制代码
Promise.all
接收一个promise对象数组为参数: 多个promise任务同时执行,若是所有成功执行,则以数组的方式返回全部 Promise 任务的执行结果。 若是有一个 Promise 任务 rejected,则只返回 rejected 任务的结果。编程
const promise1 = new Promise((reslove, reject) => {
reslove(1);
})
const promise2 = new Promise((reslove, reject) => {
reslove(2);
})
const promise3 = new Promise((reslove, reject) => {
reject(3);
})
Promise.all([promise1, promise2]).then(data => {
console.log('data', data); // [1, 2]
}, err => {
console.log('err', err);
})
Promise.all([promise1, promise2, promise3]).then(data => {
console.log('data', data);
}, err => {
console.log('err', err); // err 3
})
复制代码
Promise.race
接收一个promise对象数组为参数: 只要有一个promise对象进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理。json
// 以前有遇到给fetch设置timeout time的需求: 思路就是咱们先定义超时promise,当咱们的定时器在必定time后这个promise对象 reject. 将咱们的请求方法与这个timeoutPromise同时放入Promise.race中就能够达到timeout的效果。
const timeoutPromise = new Promise((resolve, reject) => {
setTimeout(
() => reject(new RequestException('网络超时', '当前网络环境不稳定,请稍后再试。')),
timeout,
);
})
Promise.race([fetchPromise, timeoutPromise]).then(data => ....);
复制代码
promise对象方法axios
onFulfilled
、onRejected
。then方法是异步执行的.
// onFulfilled 是用来接收promise成功的值
// onRejected 是用来接收promise失败的缘由
promise.then(onFulfilled, onRejected);
复制代码
// 注意
// onRejected 不能捕获当前onFulfilled中的异常
promise.then(onFulfilled, onRrejected);
// 能够写成:
promise.then(onFulfilled)
.catch(onRrejected);
复制代码
Promise.prototype.finally方法:无论 Promise 对象最后状态如何,都会执行的操做。(再也不ES6中,ES2018引入标准)数组
// 无论promise最后的状态,在执行完then或catch指定的回调函数之后,都会执行finally方法指定的回调函数。finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态究竟是fulfilled仍是rejected。这代表,finally方法里面的操做,应该是与状态无关的,不依赖于 Promise 的执行结果。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
复制代码
Promise.prototype.done方法:注意此方法并不在ES6以及Promise A+规范中规定以及实现。(可是不少第三方库提供了此方法的实现)
if (typeof Promise.prototype.done === 'undefined') {
Promise.prototype.done = function (onFulfilled, onRejected) {
this.then(onFulfilled, onRejected).catch(function (error) {
setTimeout(function () {
throw error;
}, 0);
});
};
}
var promise = Promise.resolve();
promise.done(function () {
JSON.parse('this is not json'); // => SyntaxError: JSON.parse
});
// done 对比 then
// 1. then方法并不会捕获当前onFulfilled中的错误,必须后面再跟catch。done中发生的异常直接抛出。
// 2. done以后不会反悔promise对象,就是done以后不能使用catch等方法组成方法链。
复制代码
4、微任务(参考:javascript的运行机制)
new Promise((resolve, reject) => {
resolve(1);
}).then(data => console.log(data));
console.log(2);
// 上面的代码是先输出2, 再输出1.
// Promise当即执行,then函数分发到微任务Event Queue,Node.js中的process.nextTick一样也是分发到微任务Event Queue。
// Promise 的回调函数不是正常的异步任务,而是微任务(microtask)。宏任务必然是在微任务以后才执行的(由于微任务其实是宏任务的其中一个步骤)。
// tip: process.nextTick()的意思就是定义出一个动做,而且让这个动做在下一个事件轮询的时间点上执行。
复制代码