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

时间:2018-03-29 17:24:24

标签: javascript reactjs promise

我正在为我的测试乐趣项目制作一些技巧原型,因为我知道我需要推迟很多事情,我认为我需要Promises。

然而,事实证明它并不起作用,我认为它的工作原理。虽然目前这对我来说不是一个问题,但我知道以后我将不得不解决这个问题。

以下是代码:

var myChart = new Chart(ctx, {
               type: 'bar',
               data: {
                   labels: chartDates,
                   datasets: [{
                       label: month,
                       data: month,
                 .....

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

有没有一些优雅的方法来解决这个没有一些奇怪的回调块?可以异步/等待这个吗?或者也许是一些可以消除大量不必要代码的库?

1 个答案:

答案 0 :(得分:5)

主要问题是你过早解决问题。在所有这些超时都完成之前,你不想解决。

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

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

然后,现在坚持使用promise语法并假设this.props.enemies是一个数组,您可以使用map为每个敌人创建一个承诺,并使用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')
    })
}
  

async / await可以帮忙吗?

是的,很重要:

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