2017-08-03 19 views
1

我正在努力在我的程序中做一個簡單的等待功能。如果可能,我想使用promise和async等待。我到目前爲止:Javascript等待條件使用承諾爲真

function waitForCondition(conditionObj) { 
    var start_time = new Date().getTime() 

    function checkFlag() { 
    if (conditionObj.arg == conditionObj.test) { 
     console.log('met'); 
     return new Promise(resolve => setTimeout(resolve, 1)); 
    } else if (new Date() > start_time + 3000) { 
     console.log('not met, time out'); 
     return new Promise(resolve => setTimeout(resolve, 1)); 
    } else { 
     window.setTimeout(checkFlag, 1000); 
    } 
    } 
    checkFlag(); 
} 

    async function run() { 
    console.log('before'); 
    await waitForCondition({arg: '1', test: '1'}) 
    console.log('after'); 
    } 
    run(); 

它應該每隔1秒檢查一次,最長時間爲3秒。控制檯應該是這樣的:

'before' 
'met' 
'after' 

回答

3

你必須return一個承諾:

function waitForCondition(conditionObj) { 
    return new Promise(resolve => { 
    var start_time = Date.now(); 
    function checkFlag() { 
     if (conditionObj.arg == conditionObj.test) { 
     console.log('met'); 
     resolve(); 
     } else if (Date.now() > start_time + 3000) { 
     console.log('not met, time out'); 
     resolve(); 
     } else { 
     window.setTimeout(checkFlag, 1000); 
     } 
    } 
    checkFlag(); 
    }); 
} 

async function run() { 
    console.log('before'); 
    await waitForCondition({arg: '1', test: '1'}) 
    console.log('after'); 
} 
run(); 

我重構你的代碼位。要獲得當前時間,請使用Date.now()。你應該可以在沒有1毫秒超時的情況下調用resolve

+0

是的,但請不要寫那樣的承諾邏輯。你應該promisify'setTimeout',沒有別的。 – Bergi

+0

@petermader謝謝你的驚人答案,這正是我想要做的。 –

0

你的功能waitForCondition隱含返回undefined。嘗試在它的末尾添加一個返回statment:

return checkFlag(); 

而且在評論mentionned,有一個條件,其中checkFlag()回報undefined,你可能想通過返回Promise處理。

+3

但只是增加了'return'是不夠的。如果條件尚未滿足,checkFlag()將返回undefined。 – PeterMader

0

我相信你真正需要的是

function waitForCondition(conditionObj) { 
    var start_time = new Date().getTime() 

    async function checkFlag() { 
    if (conditionObj.arg == conditionObj.test) { 
     console.log('met'); 
     // return something? 
    } else if (new Date() > start_time + 3000) { 
     console.log('not met, time out'); 
     // throw some error? 
    } else { 
     await new Promise(resolve => setTimeout(resolve, 1000)); 
     return checkFlag(); 
    } 
    } 
    return checkFlag(); 
} 

或循環而不是遞歸

async function waitForCondition(conditionObj) { 
    var start_time = new Date().getTime() 

    while (true) { 
    if (conditionObj.arg == conditionObj.test) { 
     console.log('met'); 
     break; // or return 
    } 
    if (new Date() > start_time + 3000) { 
     console.log('not met, time out'); 
     break; // or throw 
    } 
    await new Promise(resolve => setTimeout(resolve, 1000)); 
    } 
}