點我看看~es6
前言:可能存在闡述不許確之處,歡迎指正~promise
Promise在long time ago就活躍於Javascript社區,受到開發者歡迎,只不過到近幾年才被歸入ECMA規範。異步
咱們爲何要使用Promsie?this
由於:code
咱們不但願,過了幾個月以後,代碼只有上帝纔看得懂;
咱們不但願,回調代碼越寫越往右,只能換更大的顯示器看;
咱們但願,哪怕過了好久,代碼依舊邏輯清晰,看懂不費吹灰之力;
咱們但願,可以用本身的雙手,控制住異步流的動向,就像同步代碼同樣;
有逼格...
(歡迎補充)ip
話很少說,上源碼(採用es6/es7, 建立一個Commitment類模仿Promise)::開發
class Commitment { constructor (executor) { this.status = "pending"; this.value = void(0); this.reason = void(0); this.onResolvedCallbacks = []; this.onRejectedCallbacks = []; const resolve = (value) => { if (value instanceof Promise) { return value.then(resolve, reject) } setTimeout(() => { if (this.status === "pending") { this.status = "resolved"; this.value = value; this.onResolvedCallbacks.forEach(cb => cb(value)); } }) } const reject = (reason) => { setTimeout(() => { if (this.status === "pending") { this.status = "rejected"; this.reason = reason; this.onRejectedCallbacks.forEach(cb => cb(reason)); } }) } try { executor(resolve, reject) } catch (e) { reject(e) } } then (onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value; onRejected = typeof onRejected === "function" ? onRejected : reason => { throw reason }; const resolveCommitment = (Commitment2, x, resolve, reject) => { if (Commitment2 === x) { return reject(new TypeError("A promise cannot be resolved with itself")) } let then, called; if (x !== null && (typeof x === "object" || typeof x === "function")) { try { then = x.then; if (typeof then === "function") { then.call(x, y => { if (called) return called = true; resolveCommitment(Commitment2, y, resolve, reject); }, r => { if (called) return called = true; reject(r) }) } else { resolve(x) } } catch (e) { if (called) return called = true; reject(e) } } else { resolve(x) } } let Commitment2, x; if (this.status === "resolved") { Commitment2 = new Commitment((resolve, reject) => { setTimeout(() => { try { x = onFulfilled(this.value); resolveCommitment(Commitment2, x, resolve, reject) } catch (e) { reject(e) } }); }) } if (this.status === "rejected") { Commitment2 = new Commitment((resolve, reject) => { setTimeout(() => { try { x = onRejected(this.reason); resolveCommitment(Commitment2, x, resolve, reject) } catch (e) { reject(e) } }) }) } if (this.status === "pending") { Commitment2 = new Commitment((resolve, reject) => { this.onResolvedCallbacks.push((value)=> { try { x = onFulfilled(value); resolveCommitment(Commitment2, x, resolve, reject) } catch (e) { reject(e) } }) this.onRejectedCallbacks.push((reason) => { try { x = onRejected(reason); resolveCommitment(Commitment2, x, resolve, reject) } catch (e) { reject(e) } }) }) } return Commitment2 } }