实现一个简单的Promise
-
(1)Promise 基本使用
var p = new Promise(function(resolve, reject) { setTimeout(function() { resolve("success"); }, 1000); }); p.then(success=>{ console.log(success) });
(2)Promise A+规范
-
一个 promise 必须有3个状态,pending,fulfilled(resolved),rejected。pending 状态可以转到 fulfilled(resolved)或者rejected状态。当处于fulfilled(resolved)状态或者rejected状态的时候,状态就不可变了;
-
一个promise必须有一个then方法,then方法接受两个参数:
promise.then(onFulfilled,onRejected)
其中 onFulfilled 方法表示状态从pending——>fulfilled(resolved)时所执行的方法,而onRejected 方法表示状态从pending——>rejected时所执行的方法; -
为了实现链式调用,then 方法必须返回一个 promise
promise2 = promise1.then(onFulfilled,onRejected)
(3)实现一个 Promise
-
v1.0
const STATUS = { resolved: "resolved", rejected: "rejected", pending: "pending" }; class MyPromise { constructor(constructor) { this.status = STATUS.pending; //定义状态改变前的初始状态 this.value = undefined; //定义状态为resolved的时候的状态 this.reason = undefined; //定义状态为rejected的时候的状态 this.resolve = this.resolve.bind(this); this.reject = this.reject.bind(this); this.then = this.then.bind(this); //捕获构造异常 try { constructor(this.resolve, this.reject); } catch (e) { this.reject(e); } } resolve(value) { if (this.status === STATUS.pending) { this.value = value; this.status = STATUS.resolved; } } reject(reason) { if (this.status === STATUS.pending) { this.reason = reason; this.status = STATUS.rejected; } } then(onFullfilled, onRejected) { if (this.status === STATUS.resolved) { onFullfilled(this.value); } else if (this.status === STATUS.rejected) { onRejected(this.reason); } } }
不足:异步执行resolve时无输出,因为 then 函数会先执行,此时的状态依然是 pending
var p = new MyPromise((resolve, reject) => { setTimeout(() => { resolve(1); }, 1000); }); p.then( success => { console.log("fufilled:", success); } ); //无输出
-
v2.0(处理异步)
为了处理异步逻辑,用2个数组 onFullfilledArray 和 onRejectedArray 来保存状态改变后要执行的方法。在状态发生改变时,在 resolve(reject)中一次遍历执行数组中的方法
class MyPromise { constructor(constructor) { this.status = STATUS.pending; //定义状态改变前的初始状态 this.value = undefined; //定义状态为resolved的时候的状态 this.reason = undefined; //定义状态为rejected的时候的状态 this.onFullfilledArray = []; this.onRejectedArray = []; this.resolve = this.resolve.bind(this); this.reject = this.reject.bind(this); this.then = this.then.bind(this); //捕获构造异常 try { constructor(this.resolve, this.reject); } catch (e) { this.reject(e); } } resolve(value) { if (this.status === STATUS.pending) { this.value = value; this.status = STATUS.resolved; this.onFullfilledArray.forEach(onFullfilled => { onFullfilled(this.value); }); } } reject(reason) { if (this.status === STATUS.pending) { this.reason = reason; this.status = STATUS.rejected; this.onRejectedArray.forEach(onRejected => { onRejected(this.reason); }); } } then(onFullfilled, onRejected) { if (this.status === STATUS.pending) { this.onFullfilledArray.push(onFullfilled); this.onRejectedArray.push(onRejected); } else if (this.status === STATUS.resolved) { onFullfilled(this.value); } else if (this.status === STATUS.rejected) { onRejected(this.reason); } } }
不足:没有实现链式调用。Promise/A+规范的最大的特点就是链式调用,也就是说then方法返回的应该是一个promise
new Promise((resolve, reject) => { resolve(1); }) .then((value) => { console.log("v1",value); return value + 1; }) .then((value) => { console.log("v2",value); }); //v1 1 //v2 2
-
v3.0(链式调用)
class MyPromise { constructor(constructor) { this.status = STATUS.pending; //定义状态改变前的初始状态 this.value = undefined; //定义状态为resolved的时候的状态 this.reason = undefined; //定义状态为rejected的时候的状态 this.onFullfilledArray = []; this.onRejectedArray = []; this.resolve = this.resolve.bind(this); this.reject = this.reject.bind(this); this.then = this.then.bind(this); //捕获构造异常 try { constructor(this.resolve, this.reject); } catch (e) { this.reject(e); } } resolve(value) { if (this.status === STATUS.pending) { this.value = value; this.status = STATUS.resolved; this.onFullfilledArray.forEach(onFullfilled => { onFullfilled(this.value); }); } } reject(reason) { if (this.status === STATUS.pending) { this.reason = reason; this.status = STATUS.rejected; this.onRejectedArray.forEach(onRejected => { onRejected(this.reason); }); } } then(onFullfilled, onRejected) { let promise2 = null; let self = this; if (this.status === STATUS.pending) { promise2 = new MyPromise(function(resolve, reject) { self.onFullfilledArray.push(function() { try { resolve(onFullfilled(self.value)); } catch (e) { reject(e); //error catch } }); self.onRejectedArray.push(function() { try { reject(onRejected(self.reason)); } catch (e) { reject(e); // error catch } }); }); } else if (this.status === STATUS.resolved) { let value = this.value; promise2 = new MyPromise(function(resolve, reject) { try { //将上次一then里面的方法传递进下一个Promise的状态 resolve(onFullfilled(value)); } catch (e) { console.log("err", e); reject(e); //error catch } }); } else if (this.status === STATUS.rejected) { let reason = this.reason; promise2 = new MyPromise(function(resolve, reject) { try { //将then里面的方法传递到下一个Promise的状态里 reject(onRejected(reason)); } catch (e) { reject(e); } }); } return promise2; } }
不足:then函数里面的onFullfilled方法和onRejected方法的返回值可以是对象,函数,甚至是另一个promise
-
v4.0 (then函数中onFullfilled和onRejected方法的返回值问题)
-