javascript - 使用 promise (react+redux) 设置超时问题

标签 javascript reactjs promise

我正在为我的有趣的测试项目制作一些机制原型(prototype),因为我知道我需要延迟很多事情,所以我认为我需要 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')

            })

        }

目前我将我的状态切换为“敌人”,它立即切换回“盟友”并打印“i”值,而 setTimeout 仍在缓慢解决。

没有一些奇怪的回调 block ,有什么优雅的方法可以解决这个问题吗?异步/等待可以帮助解决这个问题吗?或者可能是一些可以消除大量不必要代码的库?

最佳答案

主要问题是您解决得太早了。在所有这些超时完成之前,您不想解决。

最简单的方法是从启用 promise 的 setTimeout 开始,如下所示:

const setTimeoutPromise = delay => new Promise(resolve => {
    setTimeout(resolve, delay);
});

然后,暂时坚持使用 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')
    })
}

另一种选择是使用具有恒定延迟的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')
    })
}

Can async/await help with this?

是的,很重要:

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

如果上面的 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')
}

关于javascript - 使用 promise (react+redux) 设置超时问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49561915/

相关文章:

Javascript promise 卡在等待对方

javascript - 我应该怎么做才能避免移动网页上的元素(html、css、jQuery)?

angular - Cordova SQLite 返回 Promise?

php - 对表单元素集的多个 AJAX 请求

javascript - ReactJS - Array.map 和键的不明确行为

javascript - react : Map multidimensional array with different keys

javascript - React - 如何从 React.Component 中剥离顶级 div

node.js - promise 绩效问题。读取文件太慢

javascript - 正确使用useState变量

javascript - jquery 移动 + 间隔 : can't stop running in the background