我陷入了困境,我有一个本机应用程序,在该应用程序中,我有一组操作以便显示视频(我之前记录过这些操作)。
我在所有操作上都有一个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,
});
}),
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 loop
和switch
里面,因为我没有得到console.log('pause outside loop');
。但是如您所见,我也没有得到console.log('set Pause');
。因此,这意味着我的承诺没有解决。
我认为问题在于在诺言中发起诺言,因为对于第一种情况(播放),它直接起作用。但是我看不到如何解决这个问题。
提前感谢社区
PS:我只放了javascript标记,因为我认为这与react或react-native无关。
答案 0 :(得分:0)
这意味着我的承诺没有解决。我认为问题在于在承诺中发起承诺。
的确。在new Promise
的执行者回调中,您仅调用setTimeout
,而不会调用resolve()
或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);
});
}
}
(您可以重构它以使用更好的循环条件,但您会明白的。)
答案 1 :(得分:-1)
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');
});