异步实现方式
Promise异步实现方式:
var promise = new Promise(function (resolve, reject) { setTimeout(function () { resolve('success'); }, 2000); }); promise.then(function (msg) { console.log(msg); }).catch(function (err) { console.log(err); })
生成器异步实现方式:
function waitSeconds(ms) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve('success'); }, ms); }) } function* gen() { var value = yield waitSeconds(2000); console.log(value); //2s后输出'success' } function run(gen) { return new Promise(function (resolve, reject) { var g = gen(); function next(nextF) { try { var re = nextF(); } catch (e) { return reject(e); } if (re.done) { return resolve(re.value); } Promise.resolve(re.value).then(function (v) { next(function () { return g.next(v); }) }, function (e) { next(function () { return g.throw(e); }) }) } next(function () { return g.next(); }) }) } run(gen);
async/await的异步实现:
function waitSeconds(ms) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve('success'); }, ms); }) } async function wait() { var value1 = await waitSeconds(2000); console.log(value1); // 2s后输出'success' var value2 = await waitSeconds(3000); console.log(value2); // 2s+3s后输出'success' } wait()
Promise原理(未整理完成):
function PromiseB(excutor) { var self = this; this._status = 'pending'; this.queue = []; excutor(function () { self.args = Array.prototype.slice.apply(arguments); self._status = 'resolved'; self.resolve.apply(self, self.args); }, function () { self.args = Array.prototype.slice.apply(arguments); self._status = 'rejected'; self.reject.apply(self, self.args); }); } PromiseB.prototype.then = function (resolve, reject) { this.queue.push([resolve, reject]); return this; } PromiseB.prototype.resolve = function (value) { var self = this; this._next(0, value); } PromiseB.prototype.reject = function (err) { var self = this; this._next(1, err); } PromiseB.prototype._next = function (i, val) { var self = this, arr, fn, ret; setTimeout(function () { if(arr = self.queue.shift()) { fn = arr[i]; ret = fn.call(self, val); if(!ret) return; if(ret instanceof PromiseB) { ret.queue = self.queue.slice(); ret.then(ret.resolve, ret.reject); } else { self.resolve(ret); } } }, 0); }
function PromiseD(fn) { var value = null, deferreds = [], state = 'pending'; this.then = function (onFulfilled, onRejected) { return new PromiseD(function (resolve, reject) { handle({ onFulfilled: onFulfilled || null, onRejected: onRejected || null, resolve: resolve, reject: reject }) }) } function handle(deferred) { if(state === 'pending') { deferreds.push(deferred); return; } var cb = state === 'fulfilled' ? deferred.onFulfilled : deferred.onRejected, ret; if(cb === null) { cb = state ==='fulfilled' ? deferred.resolve : deferred.reject; cb(value); return; } try { ret = cb(value); deferred.resolve(ret); } catch (e) { deferred.reject(e); } } function resolve(newValue) { if(newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { var then = newValue.then; if(typeof then === 'function') { then.call(newValue, resolve, reject); return; } } value = newValue; state = 'fulfilled'; finale(); } function reject(reason) { state = 'rejected'; value = reason; finale(); } function finale() { setTimeout(function () { deferreds.forEach(function (deferred) { handle(deferred); }) }, 0); } fn(resolve, reject); }