Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 传回承诺并在其他地方解决_Javascript_Promise - Fatal编程技术网

Javascript 传回承诺并在其他地方解决

Javascript 传回承诺并在其他地方解决,javascript,promise,Javascript,Promise,我想用承诺替换代码中的一些回调 我有一个循环运行的模型,使用setAnimationFrame。我想在我的模型中启动一些东西,并在完成时通知我。目前我是这样做的 doSomething(callback) { this._doSomething = true this._doneCallback = callback } step() { ... if (this._doSomething) { doItEveryStep(); if (success

我想用承诺替换代码中的一些回调

我有一个循环运行的模型,使用setAnimationFrame。我想在我的模型中启动一些东西,并在完成时通知我。目前我是这样做的

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()
不需要返回一些东西,这样我们就可以附加
。然后
到它吗?或者你只是说我们不需要一个命名的承诺,我们可以
返回新的承诺….