Javascript 传回承诺并在其他地方解决
我想用承诺替换代码中的一些回调 我有一个循环运行的模型,使用setAnimationFrame。我想在我的模型中启动一些东西,并在完成时通知我。目前我是这样做的Javascript 传回承诺并在其他地方解决,javascript,promise,Javascript,Promise,我想用承诺替换代码中的一些回调 我有一个循环运行的模型,使用setAnimationFrame。我想在我的模型中启动一些东西,并在完成时通知我。目前我是这样做的 doSomething(callback) { this._doSomething = true this._doneCallback = callback } step() { ... if (this._doSomething) { doItEveryStep(); if (success
doSomething(callback) {
this._doSomething = true
this._doneCallback = callback
}
step() {
...
if (this._doSomething) {
doItEveryStep();
if (success) {
this._doneCallback()
}
}
requestAnimationFrame(step)
}
我想改用承诺,所以我可以使用model.doSomething()。然后(()=>…)
我认为这样做会很好:
doSomething() {
this._doSomething = true
this._successPromise = new Promise()
return this._successPromise
}
step() {
...
if (this._doSomething) {
doItEveryStep();
if (success) {
this._successPromise.resolve()
}
}
requestAnimationFrame(step)
}
但是,显然我不能创建一个newpromise()
,因为我需要传入调用resolve
的函数。但是我很困惑,因为我不想触发一些异步代码——异步代码已经发生了。我只想能够选择在现有的异步循环中触发某些事件,并告诉我何时完成
很明显,我完全错了。我是否应该尝试将doSomething视为承诺?您通常会在承诺构造函数回调中编写所有导致承诺实现的异步代码 它确实需要不同的方法,然后您可以这样做,但我认为这不是一种理想的模式:保存对从promise构造函数获得的
resolve
函数的引用:
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)
}
您通常会在promise构造函数回调中编写所有导致实现承诺的异步代码 它确实需要不同的方法,然后您可以这样做,但我认为这不是一种理想的模式:保存对从promise构造函数获得的
resolve
函数的引用:
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)
}
如果你真的想在这里使用承诺,我可以看到两种选择。首先,保留回调并使用它来解决承诺:
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)
}
否则,您可以创建一个helper类,该类包装承诺并公开其解析和拒绝函数:
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)
}
如果你真的想在这里使用承诺,我可以看到两种选择。首先,保留回调并使用它来解决承诺:
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)
}
否则,您可以创建一个helper类,该类包装承诺并公开其解析和拒绝函数:
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)
}
听起来你需要的是一个事件,而不是承诺。虽然我猜在你的例子中,一个和另一个没有太大区别。@KevinB我编辑我的问题是使用
doSomething
,它更接近我的实际代码,并且更清楚地说明了我为什么希望它成为一个承诺。我想做点什么,然后,当它完成后,再做些别的。所以,doSomething
感觉它是“可以的”。但问题是,doSomething
本身并不会触发异步代码,它只是在现有循环中设置了一个标志。如果要使用承诺,您应该首先将整个事情包装在一个承诺中,而不是在您决定需要时才创建一个承诺。听起来您需要的是一个事件,而不是承诺。虽然我猜在你的例子中,一个和另一个没有太大区别。@KevinB我编辑我的问题是使用doSomething
,它更接近我的实际代码,并且更清楚地说明了我为什么希望它成为一个承诺。我想做点什么,然后,当它完成后,再做些别的。所以,doSomething
感觉它是“可以的”。但问题是,doSomething
本身不会触发异步代码,它只是在现有循环中设置一个标志,您希望在开始时将整个事情包装在一个承诺中,而不是在您决定需要承诺时才创建一个承诺。您说我们真的不需要返回此承诺。\u successPromise
。但是doSomething()
不需要返回一些东西,这样我们就可以附加。然后到它吗?或者你的意思是我们不需要指定的承诺,我们只需要返回新的承诺….
?你说我们真的不需要返回此承诺。_successPromise
。但是doSomething()
不需要返回一些东西,这样我们就可以附加。然后到它吗?或者你只是说我们不需要一个命名的承诺,我们可以返回新的承诺….
?