有时我想推迟promise构造函数的执行,但仍然可以定义promise链。我发现并略微调整了以下方法,但由于我对承诺的经验很少,我想知道
class Deferred {
constructor() {
this.promise = new Promise((r, e) => {
// arrows use this of their surrounding scope
this.resolve = r;
this.reject = e;
});
this.then = this.promise.then.bind(this.promise);
this.catch = this.promise.catch.bind(this.promise);
this.finally = this.promise.finally.bind(this.promise);
}
}
const sqrAsync = n => {
const d = new Deferred;
d.runPromise = () => typeof n === "number"
? setTimeout(d.resolve, 0, n * n)
: setTimeout(d.reject, 0, new Error("number expected"));
return d;
};
const deferred = sqrAsync(5),
deferred2 = sqrAsync("foo");
deferred
.then(console.log)
.catch(console.error)
.finally(() => console.log("clean up 1st"));
deferred2
.then(console.log)
.catch(console.error)
.finally(() => console.log("clean up 2nd"));
deferred.runPromise();
deferred2.runPromise();

我知道我可以使用userland的Task
/ Furture
实现来实现这个和其他所需的属性,我通常会这样做。但是,有时我需要ES6 Promise
互操作。
预测原因:我想分开"有效的"从我的程序的其余部分计算。
答案 0 :(得分:1)
function sqrAsync(n) {
return new Promise((resolve, reject) => {
if (typeof n === "number")
setTimeout(resolve, 0, n * n);
else
setTimeout(reject, 0, new Error("number expected"));
});
}
var start1, start2;
const p1 = new Promise(resolve => { start1 = resolve; }).then(() => sqrAsync(5));
const p2 = new Promise(resolve => { start2 = resolve; }).then(() => sqrAsync("foo"));
p1.then(console.log, console.error).finally(() => console.log("clean up 1st"));
p1.then(console.log, console.error).finally(() => console.log("clean up 2nd"));
start1();
start2();
您永远不需要推迟promise构造函数的执行。如果你需要在开始你的行动之前等待一些东西,那就是回复一个承诺 - 为这个东西做出承诺。
答案 1 :(得分:1)
您的sqrAsync
功能可以像这样重写:
function sqrAsync(n) {
if (typeof n === 'number')
return Promise.resolved(n * n);
return Promise.reject(new Error('number expected'));
}
或者,使用async
:
async function sqrAsync(n) {
if (typeof n === 'number')
return n * n;
throw new Error('number expected');
}
你的Deferred
确实更灵活,但我同意Jonas的意见,因为用例很少见。
你失去的一件事是,通过这样做,你假设Promise原型总是有then
,catch
,finally
而没有别的。如果你真的想这样做,你应该考虑扩展Promise
。例如在node.js中,不支持finally
(支持自cli标志后面的v8.1.4+)并且您的代码将抛出“无法读取未定义的属性'绑定”错误。
正如@Bergi在评论中指出的那样,对于我们假设Promise原型的问题,不绑定任何方法都会解决问题。这可能会使课程更难使用。另一种可能是Promise的looping through ownProperties来找出方法列表。我不想成为维护这段代码的人。
答案 2 :(得分:0)
执行函数由Promise实现立即执行,传递resolve和reject函数(在Promise构造函数甚至返回创建的对象之前调用执行程序。)
Promise旨在抽象异步执行的行为,以及可能的失败。你要找的是延迟执行,或者可能是懒惰的执行。我不认为Promise会为你提供一个简单的方法来实现这一目标。