Promise之API
1. Promise 构造函数:Promise(excutor){ }
executor函数:执行器 (resolve, reject) => { }
resolve函数:内部定义成功是我们调用的函数 value => { }
reject函数: 内部定义失败时我们调用的函数 reason => { }
🔉 executor 会在Promise 内部立即同步调用, 异步操作在执行器中执行
2. Promise.prototype.then()
then() 方法返回一个 Promise。它最多需要有两个参数:Promise 的成功和失败情况的回调函数.
onResolved函数:成功的回调函数(value) => { }
onRejected函数: 失败的回调函数 (reason) => { }
🔊 : 当
Promise实例的状态改变之后,不管成功还是失败,都会触发then回调函数。它能链式调用,那必然是挂载在原型上的方法,它的两个参数也都是函数,分别接收成功结果与失败原因。
❓:这里就产生问题了,我们该如何拿到
Promise实例的状态值呢,又该如何拿到成功结果或失败原因呢?
🙋:是
Promise实例调用的then方法,根据隐式绑定原则,then方法内部的this就指向Promise实例,所以我们直接从this上拿状态值。对于成功结果或失败原因,自然我们也得从this上拿。
const promise1 = new Promise((resolve, reject) => { resolve('Success!'); // reject('error!'); }); promise1.then((value) => { console.log(value); // "Success!" }, (err) => { console.log(err); // 'error!' });
简单实现
Promise.prototype.then = function(onFulfilled, onRejected){ if(this.state === FULFILLED){ typeof onFulfilled === 'function' && onFulfilled(this.value); } if(this.state === REJECTED){ typeof onRejected === 'function' && onRejected(this.reason); } if(this.state === PENDING){ // TODO } }
3. Promise.prototype.catch()
Promise对象的 **catch()**方法用于注册一个在 promise 被拒绝时调用的函数。它会立即返回一个等价的 Promise对象,这可以允许链式调用其它 promise 的方法。此方法是 Promise.prototype.then(undefined, onRejected)的一种简写形式。
let promise = new Promise(function(resolve, reject) { resolve('Success'); }); promise.then(function(value) { console.log(value); // "Success!" throw 'error!'; // 等价于 return Promise.reject('error!'); }).catch(function(e) { console.log(e); // "error" }).then(function(){ console.log('捕获到了异常'); }, function () { console.log('你好呀'); });
简单实现
Promise.prototype.catch = function (onRejected) { return this.then(null, onRejected); };
4. Promise.prototype.finally()
finally()方法指定不管promise最后的状态如何,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。
let promise = new Promise(function(resolve, reject) { resolve('Success'); }); promise.then(function(value) { console.log(value); // "Success!" return Promise.reject('error!'); }).catch(function(e) { console.log(e); // "error!!" }).then(function(){ console.log('捕获到了异常'); }).finally(()=>{ console.log('我是finall,不管promise结果如何我都要执行'); });
简单实现
Promise.prototype.finally = function (callback) { let P = this.constructor; // P 指向当前 promise 实例的构造器,简单说就是 Promise 构造函数 return this.then( value => P.resolve(callback()).then(() => value), reason => P.resolve(callback()).then(() => { throw reason }) ); };
5. Promise.all()
Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。所有实例的状态都变成fulfilled,新生成实例的状态才会变成fulfilled;只要有一个实例被rejected,新生成实例的状态就变成rejected。⏰ 注意
fulfilled状态下返回值是一个按顺序存储每一个实例返回值的数组,而rejected状态下返回值则是第一个被拒绝实例的返回值Promise.all()方法的参数可以不是数组,但必须具有Iterator接口,且返回的每个成员都是 Promise 实例
const p1 = new Promise((resolve, reject) => { resolve('hello'); }).then(result => result); const p2 = new Promise((resolve, reject) => { throw new Error('报错了'); }).then(result => result); Promise.all([p1, p2]) .then(result => console.log(result)) .catch(e => console.log(e));//Error:报错了
简单实现
Promise.all = function(iterable){ // 假定传入的参数就是数组或字符串等具有 Iterator 接口的对象,这里对参数省略过多校验 const results = []; // 用于存放结果 let index = 0; // 记录下标 let count = 0; // 记录已存放结果个数 return new Promise(function(resolve, reject){ if(iterable[Symbol.iterator]().next().done) // 判断传入的可迭代对象是空的 return resolve([]); // return 终止 for(let item of iterable){ let ind = index++; // 只要循环下标就 +1,使用 let 来让每一次循环存储一个独有的下标 Promise.resolve(item) // 迭代出来的值无论是 promise 类型还是基本类型值,都给它封成 promise .then(value =>{ results[ind] = value; count++; // 存放结果后才 +1 if(count === iterable.length) // 长度相同即判定都完成了 resolve(results); }, reason => { reject(reason); // //只要有一个失败,return 的 promise 状态就为 reject }) } }); }
6. Promise.allSettled()
该方法用来确定一组异步是否都结束(不管成功或失败)。方法接受一个数组作为参数,只有当参数数组中所有 Promise对象 都发生变化,返回的 Promise 对象才会发生状态变更。
const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const allSettledPromise = Promise.allSettled([resolved, rejected]);
allSettledPromise.then(function (results) {
console.log(results);
});
简单实现
Promise.allSettled = function(iterable){ // 假定传入的参数就是数组或字符串等具有 Iterator 接口的对象,这里对参数省略过多校验 const results = []; // 用于存放结果 let index = 0; // 记录下标 let count = 0; // 记录已存放结果个数 return new Promise(function(resolve, reject){ if(iterable[Symbol.iterator]().next().done) // 判断传入的可迭代对象是空的 return resolve([]); // return 终止 for(let item of iterable){ let ind = index++; // 只要循环下标就 +1,使用 let 来让每一次循环存储一个独有的下标 Promise.resolve(item) // 迭代出来的值无论是 promise 类型还是基本类型值,都给它封成 promise .then(value =>{ results[ind] = { status: 'fulfilled', value }; count++; if(count === iterable.length) // 长度相同即判定都完成了 resolve(results); }, reason => { results[ind] = { status: 'rejected', reason }; count++; if(count === iterable.length) // 长度相同即判定都完成了 resolve(results); // 因为包装实例的状态只会变为 fulfilled }) } }); }
7. Promise.race()
该方法同样是将多个 Promise 实例包装成一个新的 Promsie 实例,该方法与 Promise.all()方法一样,区别是该方法中只要参数之中有一个实例率先改变状态,该方法的实例状态跟着改变,那个率先改变的 Promise 实例的返回值就传递给该方法实例的回调函数。
const p = Promise.race([ fetch('./index.js'), new Promise(function (resolve, reject) { setTimeout(() => reject(new Error('request timeout')), 5000) }) ]); p.then(console.log).catch(console.error);
简单实现
Promise.race = function(iterable){ // 假定传入的参数就是数组或字符串等具有 Iterator 接口的对象,这里对参数省略过多校验 return new Promise(function(resolve, reject){ for(let item of iterable){ Promise.resolve(item) .then(value => { resolve(value); }, reason => { reject(reason); }) } }) }
8. Promise.any()
Promise.any() 和 Promise.race()方法很像,唯一区别就是Promise.any()不会因为某个 Promise 变成 rejected 状态而结束,必须等到所有参数 Promise 变成 rejected 状态才会结束。
const resolved = Promise.resolve(42); const rejected = Promise.reject(-1); const alsoRejected = Promise.reject(Infinity); Promise.any([resolved, rejected, alsoRejected]).then(function (result) { console.log(result); // 42 }); Promise.any([rejected, alsoRejected]).catch(function (results) { console.log(results instanceof AggregateError); // true console.log(results.errors); // [-1, Infinity] });
简单实现
Promise.any = function(iterable){ // 假定传入的参数就是数组或字符串等具有 Iterator 接口的对象,这里对参数省略过多校验 const err = new AggregateError(); // 用于存放错误 let index = 0; // 记录下标 let count = 0; // 记录已存放结果个数 return new Promise(function(resolve, reject){ if(iterable[Symbol.iterator]().next().done) // 判断传入的可迭代对象是空的 return resolve([]); // return 终止 for(let item of iterable){ let ind = index++; // 只要循环下标就 +1,使用 let 来让每一次循环存储一个独有的下标 Promise.resolve(item) .then(value => { resolve(value); }, reason => { err[ind] = (new Error(reason)); count++; if(count === iterable.length) // 长度相同即判定都完成了 reject(err); }) } }) }
9. Promise.resolve()
该方法能够将现有对象转换为 Promise 对象。
Promise.resolve('foo')
// 相当于
new Promise(resolve => resolve('foo'))
🔉 传入的参数如果是
promise类型,不作处理直接返回。
简单实现
Promise.resolve = function(value) { if(value instanceof Promise) return value const promise = new Promise(function(resolve, reject) { resolvePromise(promise, value, resolve, reject) }); return promise; }
10. Promise.reject()
返回一个带有拒绝原因的 Promise 对象。
Promise.reject(new Error('fail')).then(() => { }, (error) => { console.error(error); });
简单实现
Promise.reject = function(reason) { return new Promise(function(resolve, reject) { reject(reason) }); }
浙公网安备 33010602011771号