簡體   English   中英

解決 promise 內部的 promise

[英]Resolve a promise inside a promise

我遇到了一個問題,我有一個 react-native 應用程序,我有一組動作來顯示視頻(我之前記錄了這些動作)。

我對所有動作都有一個 for 循環,需要等待視頻達到某個時間戳才能觸發動作。 為此,我使用開關來識別我的所有操作,並在內部等待 promise 以便在良好的時間戳觸發操作。

這是我的代碼:

  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,
            });
          }),
            console.log('pause outside loop');
          break;
        case 'changePlayRate':
          console.log('changePlayRate');
          this.videoPlayerRef.setState({
            playRate: action.playRate,
          });
          break;
        default:
          console.log(`case ${action.type} not handled`);
      }
    }
  };

和日志: 在此處輸入圖像描述

我們可以看到我停留在for loopswitch內,因為我沒有得到console.log('pause outside loop'); . 但正如你所看到的,我沒有得到console.log('set Pause'); 也。 所以這意味着我的 Promise 沒有解決。

我認為問題是在 promise 內啟動 promise 因為對於第一種情況(播放)它直接工作。 但我不知道如何解決這個問題。

預先感謝社區

PS:我只放了 javascript 標簽,因為我認為這與反應無關,也與 react-native 無關。

這意味着我的 Promise 沒有解決。 我認為問題在於在 promise 中啟動 promise。

的確。 new Promise的執行器回調中,您只調用setTimeout而從不調用resolve()reject() 100 毫秒后的isTimestampReached調用確實創建並返回了它自己的 promise,原來的“外部”promise 永遠不會被解析。 你可以通過這樣做來解決這個問題

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);
    });
  }
}

(你可以重構它以使用更好的循環條件,但你明白了)。


  await this.isTimestampReached(action.timestamp).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');
          });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM