简述ES6中的Promise对象
Promise 的含义
所谓Promise,行为上是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。语法上,Promise 是一个对象,它可以获取异步操作的消息。
- Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),一旦状态改变,就不会再变。只有两种可能,从pending变为fulfilled和从pending变为rejected。
基本用法
const promise = new Promise(function(resolve, reject) { // ... some code
if (/* 异步操作成功 */){ resolve(value); } else { reject(error); }});
promise.then(function(value) { // success}, function(error) { // failure});
then方法
- then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的。
- then方法返回的是一个新的Promise实例。因此可以采用链式写法,即then方法后面再调用另一个then方法。
catch方法
- catch()方法是
.then(null, rejection)或.then(undefined, rejection)
的别名,用于指定发生错误(rejected状态或捕获的代码运行错误)时的回调函数。Promise 对象的错误具有“冒泡”性质。会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。
finally方法
finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。finally本质上是then方法的特例。
promise.finally(() => { // 语句});
// 等同于promise.then( result => { // 语句 return result; }, error => { // 语句 throw error; });
具体实现
Promise.prototype.finally = function (callback) { let P = this.constructor; return this.then( value => P.resolve(callback()).then(() => value), reason => P.resolve(callback()).then(() => { throw reason }) );};
Promise的实现
// 1. promise status状态不可逆// 2. catch处理指定错误(rejected状态或捕获的代码运行错误)// 3. then返回的是promise,以实现链式调用
class MyPromise { constructor(executor) { this.status = 'pending'; this.value = undefined; this.reason = undefined; this.onFulfilledCallbacks = []; this.onRejectedCallbacks = []; const resolve = (value) => { if (this.status === 'pending') { this.status = 'fulfilled'; this.value = value; this.onFulfilledCallbacks.forEach(fn => fn()); } }; const reject = (reason) => { this.status = 'rejected'; this.reason = reason; this.onRejectedCallbacks.forEach(fn => fn()); };
try { executor(resolve, reject); } catch (error) { reject(error); } }
then(onFulfilled, onRejected) { return new MyPromise((resolve, reject) => { const fulfilled = () => { try { if (typeof onFulfilled === 'function') { resolve(onFulfilled(this.value)); } else { resolve(this.value); } } catch (error) { reject(error) } }; const rejected = () => { try { if (typeof onRejected === 'function') { resolve(onRejected(this.reason)); } else { reject(this.reason); } } catch (error) { reject(error); } }; switch (this.status) { case 'fulfilled': fulfilled(); break; case 'rejected': rejected(); break; default: this.onFulfilledCallbacks.push(() => fulfilled()); this.onRejectedCallbacks.push(() => rejected()); } });
}
catch(onRejected) { return this.then(null, onRejected); }
finally(cb) { this.then(() => cb(), () => cb()); }}