Promise
v1:基本实现
// 最基础的Promisevar pending = 0;var fulfilled = 1;var rejected = 2;function Promisee(fn) { var state = pending; var value = null; function fulfill(result) { state = fulfilled; value = result; } function reject(err) { state = reject; value = err; } fn(fulfill, reject); this.then = function (onFulfilled, onRejected) { if (state === fulfilled) { onFulfilled(value); } if (state === rejected) { onRejected(value); } };}var p = new Promisee((resove, reject) => { resove('hello world');}).then((res) => { console.log(res);});
v2:加上异步机制
// 使 promse 具有异步功能var pending = 0;var fulfilled = 1;var rejected = 2;function Promisee(fn) { var state = pending; var value = null; var handler = []; function fulfill(result) { state = fulfilled; value = result; handler.forEach((handle) => handle.onFulfilled(result)); } function reject(err) { state = reject; value = err; handler.forEach((handle) => handle.onRejected(err)); } fn(fulfill, reject); this.then = function (onFulfilled, onRejected) { if (state === pending) { handler.push({ onFulfilled, onRejected }); } if (state === fulfilled) { onFulfilled(value); } if (state === rejected) { onRejected(value); } };}var p = new Promisee((resove, reject) => { setTimeout(() => { resove('hello world promise'); }, 200);}).then((res) => { console.log(res);});
v3 :链式调用
// 使 promise 链式调用function Promisee(fn) { var pending = 0; var fulfilled = 1; var rejected = 2; var handler = []; var state = pending; var value = null; function fulfill(result) { state = fulfilled; value = result; console.log(handler); handler.forEach((handle) => handle.onFulfilled(result)); } function reject(err) { state = reject; value = err; handler.forEach((handle) => handle.onRejected(err)); } fn(fulfill, reject); this.then = function (onFulfilled, onRejected) { return new Promisee((resolve, reject) => { const fulfillFn = (value) => resolve(onFulfilled(value)); const rejectFn = (err) => reject(onRejected(err)); if (state === pending) { handler.push({ onFulfilled: fulfillFn, onRejected: rejectFn }); } if (state === fulfilled) { resolve(fulfillFn); } if (state === rejected) { reject(rejectFn); } }); };}var p = new Promisee((resove, reject) => { setTimeout(() => { resove('hello world promise'); }, 200);}) .then((res) => { console.log(res + 'abc'); return res + 12345; }) .then((res2) => { return res2 + 67890; }) .then((res3) => { console.log(res3); });
v4 :支持中途 promise 返回
// return 支持 promise 返回值class Promisee { constructor(fn) { this.pending = 0; this.fulfilled = 1; this.rejected = 2; this.handler = []; this.state = this.pending; this.value = null; const fulfill = (result) => { this.state = this.fulfilled; this.value = result; this.handler.forEach((handle) => handle.onFulfilled(result)); }; const reject = (err) => { this.state = reject; this.value = err; this.handler.forEach((handle) => handle.onRejected(err)); }; const getThen = (value) => { const t = typeof value; if (t === 'object' || t === 'function') { var then = value.then; if (typeof then === 'function') { return then; } } else { return null; } }; const resolve = (result) => { const then = getThen(result); if (then) { then.call(result, resolve, reject); return; } fulfill(result); }; fn(resolve, reject); } then(onFulfilled, onRejected) { return new Promisee((resolve, reject) => { const fulfillFn = (value) => resolve(onFulfilled(value)); const rejectFn = (err) => reject(onRejected(err)); if (this.state === this.pending) { this.handler.push({ onFulfilled: fulfillFn, onRejected: rejectFn }); } if (this.state === this.fulfilled) { fulfillFn(this.value); } if (this.state === this.rejected) { rejectFn(this.value); } }); } static resolve = function (value) { return new Promisee(function (resolve) { resolve(value); }); };}console.log('a');var p = new Promisee((resove, reject) => { // setTimeout(() => { resove('hello world promise'); // }, 200);}) .then((res) => { console.log('b'); return res + 12345; }) .then((res2) => { return Promisee.resolve(res2); }) .then((res3) => { console.log(res3, 'xxx'); });console.log('c');
v5: 支持微任务机制
// return 添加微任务机制class Promisee { constructor(fn) { this.pending = 0; this.fulfilled = 1; this.rejected = 2; this.handler = []; this.state = this.pending; this.value = null; const fulfill = (result) => { this.state = this.fulfilled; this.value = result; this.handler.forEach((handle) => handle.onFulfilled(result)); }; const reject = (err) => { this.state = this.rejected; this.value = err; this.handler.forEach((handle) => handle.onRejected(err)); }; const getThen = (value) => { const t = typeof value; if (t === 'object' || t === 'function') { var then = value.then; if (typeof then === 'function') { return then; } } else { return null; } }; const resolve = (result) => { try { const then = getThen(result); if (then) { then.call(result, resolve, reject); return; } fulfill(result); } catch (err) { reject(err); } }; fn(resolve, reject); } done(fulfillFn, rejectFn) { queueMicrotask(() => { if (this.state === this.pending) { this.handler.push({ onFulfilled: fulfillFn, onRejected: rejectFn }); } if (this.state === this.fulfilled) { fulfillFn(this.value); } if (this.state === this.rejected) { rejectFn(this.value); } }); } then(onFulfilled, onRejected) { return new Promisee((resolve, reject) => { let fulfillFn, rejectFn; if (typeof onFulfilled === 'function') { fulfillFn = (value) => resolve(onFulfilled(value)); } else { fulfillFn = (value) => resove(value); } if (typeof onRejected === 'function') { rejectFn = (err) => reject(onRejected(err)); } else { rejectFn = (value) => reject(value); } this.done(fulfillFn, rejectFn); }); } catch(onRejected) { return this.then(null, onRejected); } static resolve = function (value) { return new Promisee(function (resolve) { resolve(value); }); };}console.log('a');var p = new Promisee((resove, reject) => { setTimeout(() => { resove('hello world promise'); }, 200);}) .then((res) => { throw new Error('this is error'); }) .then((res2) => { return Promisee.resolve(res2); }) .catch((err) => { console.log(err); });console.log('c');