簡體   English   中英

設置承諾超時問題(react + redux)

[英]Set timeout issue with promise (react+redux)

我正在為測試趣味項目制作一些機械模型,因為我知道我將需要延遲很多事情,所以我認為我將需要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仍在緩慢地解決。

沒有一些怪異的回調塊,有沒有什么優雅的方法可以解決此問題? 異步/等待可以幫助這個嗎? 還是一些可以消除許多不必要代碼的庫?

主要問題是您解決得太早。 在所有這些超時完成之前,您不希望解決。

最簡單的方法是從啟用了promise的setTimeout ,如下所示:

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

然后, this.props.enemies使用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')
    })
}

異步/等待可以幫助這個嗎?

是的,很重要:

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

暫無
暫無

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

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