Mat*_*zur 1 javascript promise reactjs
我正在为我的测试乐趣项目制作一些机制原型,因为我知道我需要延迟很多事情,我认为我需要Promises.
然而,事实证明它不起作用,我认为它的工作原理.虽然目前这对我来说不是一个问题,但我知道以后我将不得不解决这个问题.
这是代码:
if(nextProps.mechanics.turn === 'enemy'){
let enemyTurnPromise = new Promise((resolve, reject) =>{
let i = 0;
_.forEach(this.props.enemies, (enemy, index) =>{
setTimeout(this.handleEnemyAttack, 1000 * index)
i++;
})
resolve(i)
})
enemyTurnPromise.then(r =>{
console.log('test', r);
this.props.switchTurn('ally')
})
}
Run Code Online (Sandbox Code Playgroud)
目前我将状态切换为"敌人"并立即切换回"盟友"并打印"i"值,而setTimeout仍在缓慢解析.
没有一些奇怪的回调块,有没有任何优雅的方法来解决这个问题?可以异步/等待这个吗?或者也许是一些可以消除大量不必要代码的库?
主要问题是你太早解决了.在完成所有这些超时之前,您不想解决.
最简单的方法是从启用promise开始setTimeout,如下所示:
const setTimeoutPromise = delay => new Promise(resolve => {
setTimeout(resolve, delay);
});
Run Code Online (Sandbox Code Playgroud)
然后,现在坚持使用promise语法,假设this.props.enemies是一个数组,你可以使用map为每个敌人创建一个promise,并Promise.all用来等待所有这些完成:
if(nextProps.mechanics.turn === 'enemy') {
Promise.all(this.props.enemies.map((enemy, index) =>
setTimeoutPromise(1000 * index).then(() => this.handleEnemyAttack(enemy))
)).then(r => {
console.log('test', /*...not sure what `r` is meant to be here... */);
this.props.switchTurn('ally')
})
}
Run Code Online (Sandbox Code Playgroud)
另一个选择是使用reduce持续延迟并等待每个敌人的攻击在下一个之前完成:
if(nextProps.mechanics.turn === 'enemy') {
this.props.enemies.reduce((p, enemy) =>
p.then(() => setTimeoutPromise(1000)).then(this.handleEnemyAttack(enemy))
, Promise.resolve())
.then(r => {
console.log('test', /*...not sure what `r` is meant to be here... */);
this.props.switchTurn('ally')
})
}
Run Code Online (Sandbox Code Playgroud)
可以异步/等待这个吗?
是的,很棒的时间:
if(nextProps.mechanics.turn === 'enemy') {
(async () => {
for (const enemy of this.props.enemies) {
await setTimeoutPromise(1000);
this.handleEnemyAttack(enemy);
}
console.log('test', /*not sure what r is meant to be here*/);
this.props.switchTurn('ally')
}).catch(e => {
// Handle error
});
}
Run Code Online (Sandbox Code Playgroud)
如果if上面已经在async函数中,我们可以删除该位:
if(nextProps.mechanics.turn === 'enemy') {
for (const enemy of this.props.enemies) {
await setTimeoutPromise(1000);
this.handleEnemyAttack(enemy);
}
console.log('test', /*not sure what r is meant to be here*/);
this.props.switchTurn('ally')
}
Run Code Online (Sandbox Code Playgroud)