我试图从头开始实现承诺。
问题:
我不确定如何实现“最终”? (我猜想最终会 然后在执行并捕获。 (仅一次))
如果您认为可以对我的代码进行任何重构,请随时提出建议。这是我天真地兑现承诺的尝试。
这是我的实现方式
function Promisify(fn) {
let status = 0; // 0 = unfulfilled, 1 = resolved, 2 = rejected
let result;
let error;
let thenFns = [];
let catchFns = [];
let finallyFn = undefined;
// Public Methods.
this.then = function(fn) {
thenFns.push(fn);
doThen();
return this; // for chaining
};
this.catch = function(fn) {
catchFns.push(fn);
doCatch();
return this; // for chaining
};
// TODO: Implement finally
this.finally = function(fn) {
finallyFn = fn;
// dofinally(fn);
return this;
}
// Private Methods
function resolve(r) {
if (status) throw Error('can not resolve, already handled');
status = 1;
result = r;
doThen();
}
function reject(e) {
if (status) throw Error('can not reject, already handled');
status = 2;
error = e;
doCatch();
}
function doThen() {
if (status === 1) {
while(thenFns.length) {
thenFns.shift()(result);
}
}
}
function doCatch() {
if (status === 2) {
if (catchFns.length === 0) {
console.error('uncaught error')
}
while(catchFns.length) {
catchFns.shift()(error);
}
}
}
try {
fn(resolve, reject);
} catch (e) {
reject(e);
}
}
// ======== QUESTION: Caller ================
const demoFail = new Promisify((resolve, reject) => {
setTimeout(function() {
reject('Howdy! from DemoFail')
}, 1000);
});
demoFail
.then(val => console.log("DemoFail Then!!"))
.catch(console.error) //Should throw an error.
.then(val => console.log("Second then!"))
.catch(
(err) => {
throw new Error('error', err);
})
.finally(val => console.log("Executed Finally"))
答案 0 :(得分:1)
实现中缺少一些内容:
.then()
需要返回一个新的承诺,而不是相同的承诺。.then()
处理程序的返回值(如果不是承诺)将成为在步骤#1中返回的新返回的承诺的解析值。.then()
处理程序的返回值是一个Promise,则直到从.then()
处理程序返回的Promise解析或拒绝该值之前,步骤1中新返回的Promise才会解析。 .then()
处理程序时,您需要在对处理程序的调用周围进行try / catch,因为如果处理程序抛出,则将返回到步骤1的承诺变成拒绝的承诺,抛出错误为拒绝原因。.catch()
处理程序都有类似的逻辑(它还会返回一个新的Promise,并且该处理程序的返回值会影响从步骤#1新返回的Promise)。
.then()
或.catch()
回调fns时,还需要存储为每个回调单独返回的新创建的Promise,因为该Promise将受到返回值或抛出的异常的影响回调。涵盖此方面的规范本身非常简单。您可以阅读here。而且,这是该规范的an implementation。
您的简单版本看起来可能像fn().then()
这样的一个承诺级别,但是它没有进行正确的链接并且没有在处理程序中捕获异常,也没有注意处理程序中的返回值这些都是承诺的相当基本的行为。不幸的是,没有超级简单的方式来写包括基本行为在内的承诺。只需更多代码即可支持它们。