Last active
August 31, 2021 01:21
-
-
Save LeeeeeeM/1cef60fb47adddc65785488d937ab546 to your computer and use it in GitHub Desktop.
实现一个Promise
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 实现一个promise 拥有then方法 | |
function noop() { | |
} | |
function resolve(promise) { | |
return function(value) { | |
if (promise._status !== 'pending') { | |
return; // 如果是fullfilled或者rejected,不可逆 | |
} | |
promise._status = 'fullfilled'; | |
promise._value = value; | |
run(promise); | |
} | |
} | |
function reject(promise) { | |
return function(reason) { | |
if (promise._status !== 'pending') { | |
return; // 如果是fullfilled或者rejected,不可逆 | |
} | |
promise._status = 'rejected'; | |
promise._value = reason; | |
run(promise); | |
} | |
} | |
function run(promise) { | |
if (promise._status === 'pending') { | |
return; | |
} | |
var value = promise._value; | |
var callbacks = promise._status === 'fullfilled' ? promise._doneCallbacks : promise._failCallbacks; | |
setTimeout(function() { | |
for (var i = 0; i < callbacks.length; i++) { | |
callbacks[i](value); | |
} | |
}); | |
promise._doneCallbacks = []; | |
promise._failCallbacks = []; | |
} | |
function Promise(resolver) { | |
this._status = 'pending'; // pending fullfilled rejected | |
this._value = undefined; | |
this._doneCallbacks = []; | |
this._failCallbacks = []; | |
resolver(resolve(this), reject(this)); | |
} | |
function closureCallback(promise, action, flag) { | |
return function(value) { | |
if (typeof action === 'function') { | |
var result; | |
try { | |
result = action(value); | |
} catch(e) { | |
reject(promise)(e); | |
} | |
if (result === promise) { | |
var reason = new Error('recycle..is..not..allowed'); | |
reject(promise)(reason); | |
} else if (result instanceof Promise) { | |
result.then(function(data) { | |
resolve(promise)(data) | |
}, function(reason) { | |
reject(promise)(reason); | |
}) | |
} else { | |
resolve(promise)(result); | |
} | |
} else { | |
flag === 'resolved' ? resolve(promise)(value) : reject(promise)(value); | |
} | |
} | |
}; | |
Promise.prototype.then = function(onResolve, onReject) { | |
var promise = new Promise(function() { | |
}); // 此处仅仅保证promise的传参相同,并无其他作用。 | |
/** | |
* 同一个promise 可能会 var a = new Promise(); | |
* a.then(); | |
* a.then(); | |
* 同时保证上一个promise能引用本个promise,引入闭包 | |
*/ | |
this._doneCallbacks.push(closureCallback(promise, onResolve, 'resolved')); | |
this._failCallbacks.push(closureCallback(promise, onReject, 'rejected')); | |
run(this); | |
return promise; | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
line 59 return