我想用Promises替换我代码中的一些回调。
我有一个使用setAnimationFrame在循环中运行的模型。我想在我的模型中启动一些东西并在完成后通知我。目前我是这样做的。
doSomething(callback) {
this._doSomething = true
this._doneCallback = callback
}
step() {
...
if (this._doSomething) {
doItEveryStep();
if (success) {
this._doneCallback()
}
}
requestAnimationFrame(step)
}
我想使用promises,所以我可以使用model.doSomething().then( () => ... )
以下是我认为这样做的好方法:
doSomething() {
this._doSomething = true
this._successPromise = new Promise()
return this._successPromise
}
step() {
...
if (this._doSomething) {
doItEveryStep();
if (success) {
this._successPromise.resolve()
}
}
requestAnimationFrame(step)
}
但是,显然我不能只创建new Promise()
,因为我需要将调用resolve
的函数传递给Promise。但我很困惑,因为我不想触发一些异步代码 - 异步代码已经发生。我只是希望能够在现有的异步循环中触发一些事情,并告诉我它何时完成。
doSomething
视为承诺?
答案 0 :(得分:2)
您通常会拥有所有异步代码,这些代码可以实现在promise构造函数回调中编码的promise。
它真的你需要不同的颜色,然后你可以这样做,但我认为这不是一个理想的模式:保存对resolve
的引用你从promise构造函数得到的函数:
doSomething() {
this._doSomething = true
return new Promise( (resolve, reject) => {
this.resolve = resolve; // Save the reference
})
// We don't need a reference to this._successPromise
}
step() {
...
if (this._doSomething) {
doItEveryStep();
if (success) {
this.resolve() // We have the reference
}
}
requestAnimationFrame(step)
}
答案 1 :(得分:1)
如果你真的想在这里使用诺言,我可以看到两种选择。首先,保持回调并使用它来解决承诺:
doSomething() {
this._doSomething = true
// The || is to prevent the promise from being recreated if this
// method is called twice.
this._successPromise = this._successPromise || new Promise((resolve, reject) => {
this._doneCallback = resolve
})
return this._successPromise
}
step() {
...
if (this._doSomething) {
doItEveryStep();
if (success) {
this._doneCallback() // Resolves the original promise...
}
}
requestAnimationFrame(step)
}
否则,您可以创建一个包装承诺的帮助程序类,并公开其解析和拒绝函数:
class Deferred {
promise;
resolve;
reject;
constructor() {
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
})
}
}
doSomething() {
this._doSomething = true
this._successPromise = this._successPromise || new Deferred()
return this._successPromise.promise
}
step() {
...
if (this._doSomething) {
doItEveryStep();
if (success) {
this._successPromise.resolve()
}
}
requestAnimationFrame(step)
}