为了账号安全,请及时绑定邮箱和手机立即绑定

在承诺中解决承诺

在承诺中解决承诺

墨色风雨 2022-12-22 15:45:29
我遇到了一个问题,我有一个本机反应应用程序,我有一组操作来显示视频(我之前记录了这些操作)。我对所有动作都有一个 for 循环,需要等待视频达到某个时间戳才能触发动作。为此,我使用一个开关来识别我所有的动作,并在内部等待一个承诺,以便在好的时间戳触发动作。这是我的代码:  isTimestampReached = (timestampToWait) => {    console.log(      `timestampToWait: ', ${timestampToWait}, currentTime: ${this.videoPlayerRef.controlButtonRef.getCurrentTime()}`,    );    return new Promise((resolve, reject) => {      if (        timestampToWait <          this.videoPlayerRef.controlButtonRef.getCurrentTime() + 0.05 &&        timestampToWait >          this.videoPlayerRef.controlButtonRef.getCurrentTime() - 0.05      ) {        console.log('timestamp Reached !');        resolve(true);      } else {        setTimeout(this.isTimestampReached, 100, timestampToWait);      }    });  };  previewRecording = async () => {    this.resetPlayer();    const {recordedActions} = this.state;    console.log('recordedActions: ', recordedActions);    for (const action of recordedActions) {      console.log('action', action);      switch (action.type) {        case 'play':          console.log('launch play');          // if (await this.isTimestampReached(action.timestamp)) {  // this is the same as the line under          await this.isTimestampReached(action.timestamp).then(() => {            this.videoPlayerRef.setState({              paused: false,            });            console.log('setPlay');          });          break;        case 'pause':          console.log('launch pause');          await this.isTimestampReached(action.timestamp).then(() => {            console.log('set Pause');            this.videoPlayerRef.setState({              paused: true,            });          }),      }    }  };和日志:我们可以看到我待在和里面for loop,switch因为我没有得到console.log('pause outside loop');。但正如你所看到的,我也不明白console.log('set Pause');。所以这意味着我的承诺没有解决。我认为问题在于在承诺中启动承诺,因为对于第一种情况(播放)它直接起作用。但我不知道如何解决这个问题。预先感谢社区PS:我只放了 javascript 标签,因为我认为这与 react 或 react-native 无关。
查看完整描述

2 回答

?
慕桂英546537

TA贡献1848条经验 获得超10个赞

这意味着我的 Promise 没有解决。我认为问题在于在承诺中发起承诺。


的确。在 的执行者回调中new Promise,您只调用setTimeout但从不调用resolve()or reject()。100 毫秒后的isTimestampReached调用确实创建并返回了自己的承诺,原始的“外部”承诺从未得到解决。你可以通过做来解决这个问题


setTimeout(() => {

  resolve(this.isTimestampReached(timestampToWait);

}, 100);

但是使用async/await进行轮询要容易得多:


async isTimestampReached(timestampToWait) {

  while (true) {

    const currentTime = this.videoPlayerRef.controlButtonRef.getCurrentTime();

    console.log(`timestampToWait: ${timestampToWait}, currentTime: ${currentTime}`);

    if (timestampToWait < currentTime + 0.05 &&

        timestampToWait > currentTime - 0.05) {

      console.log('timestamp Reached !');

      return true;

    }

    await new Promise(resolve => {

      setTimeout(resolve, 100);

    });

  }

}

(您可以重构它以使用更好的循环条件,但您明白了)。


查看完整回答
反对 回复 2022-12-22
?
呼啦一阵风

TA贡献1802条经验 获得超6个赞

  await this.isTimestampReached(action.timestamp).then(() => {

then 不会被执行,因为你等待


使用以下


const res =   await this.isTimestampReached(action.timestamp)


  this.videoPlayerRef.setState({

              paused: false,

            });

            console.log('setPlay');

或删除等待


 this.isTimestampReached(action.timestamp).then(() => {

            this.videoPlayerRef.setState({

              paused: false,

            });

            console.log('setPlay');

          });


查看完整回答
反对 回复 2022-12-22
  • 2 回答
  • 0 关注
  • 56 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信