我在 main 函式中使用了 await 關鍵字來等待對 poll() 的異步函式呼叫完成,但對 my_plot 的函式呼叫是在 poll() 函式完成之前進行的。
async function main() {
getParametersData()
await poll()
my_plot()
}
async function getData() {
const response = await fetch(API)
const message = await response.json()
return message
}
async function poll(count = 1) {
console.log(`Polling ${count}`);
try {
const data = await getData();
if (data && Object.keys(data).length !== 0) {
console.log("Poll", data)
return;
} else {
setTimeout(poll, 5000, count);
}
}
catch (err) {
console.log(`${err}. Polling again in 5 seconds.`);
setTimeout(poll, 5000, 1);
}
}
async function my_plot() {
console.log("my plot")
}
代碼輸出:
Polling 1
my plot
Polling 2
Polling 3
Poll [1,2,3]
預期的:
Polling 1
Polling 2
Polling 3
Poll [1,2,3]
my plot
uj5u.com熱心網友回復:
不要setTimeout
直接在async
函式內使用。相反,使用Promise
基于包裝器。
令人驚訝的是,現代 ECMAScript 沒有Promise
基于內置版本的setTimeout
,但實作起來很簡單:
function delay( timeout ) {
if( typeof timeout !== 'number' || timeout < 0 ) throw new Error( "Timeout must be a non-negative integer milliseconds delay value." );
return new Promise( function( resolve ) {
setTimeout( resolve, timeout );
});
}
- 然后你可以
poll
用“真正的”while
回圈重寫你的函式,就像這樣(如下)。 - 我認為你的
poll
函式應該回傳一個true
/false
值來向呼叫者指示成功或失敗,如果你需要的話。 - 考慮使用
typeof
而不是像這樣的不太安全的檢查Object.keys(data).length
- 或者至少在使用之前使用typeof
檢查。Object.keys
- 雖然煩人
typeof null === 'object'
,所以你總是需要!== null
檢查,抱怨...... - 作為替代方案,考慮擁有自己的型別保護功能(是的,我知道這不是 TypeScript),這樣您就可以獲得更強大的保證,
data
其中包含您需要的內容(因為 JS 沒有靜態型別檢查)。
- 雖然煩人
async function poll( count = 1 ) {
console.log(`Polling ${count}`);
let i = 0;
do {
try {
const data = await getData();
if( isMyData( data ) ) {
return true;
}
}
catch( err ) {
console.error( err );
}
console.log( "Polling again in 5 seconds." );
await delay( 5000 );
i ;
}
while( i < count );
console.log( `Gave up after ${count} attempts.` );
return false;
}
// Type-guard:
function isMyData( data ) {
return (
( typeof data === 'object' )
&&
( data !== null )
&&
( 'this is my object' in data )
&&
( data['there are many like it but this one is mine'] )
&&
( data.myJavaScriptEngineIsMyBestFriend )
&&
data.itIsMyLife
&&
data.withoutMe_javaScriptIsUseless
&&
data.withoutJavaScript_iAmUseLess > 0
);
}
請注意,如果您打算捕獲由getData
您拋出的錯誤,則應使用最小范圍的try
而不是在其中包含更多邏輯,因為通常您不想捕獲不相關的錯誤。
uj5u.com熱心網友回復:
使用How to make a promise from setTimeout的答案,您可以使用傳統回圈。
function later(delay, value) {
return new Promise(resolve => setTimeout(resolve, delay, value));
}
async function poll() {
for (let count = 1;; count ) {
console.log(`Polling ${count}`);
try {
const data = Math.random(); // simulated data
if (data < 0.2) { // simulated 20% success rate
console.log("Poll", data)
return data;
} else {
console.log("Retrying in 5 seconds");
await later(5000);
}
} catch (err) {
console.log(`${err}. Polling again in 5 seconds.`);
count = 1;
await later(5000);
}
}
}
async function main() {
console.log("Start");
await poll();
console.log("Poll done");
}
main();
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/395447.html
標籤:javascript 异步等待
上一篇:在Djangobootstrap專案中,顯示回圈元素中第一張卡片的吐司訊息
下一篇:返回列表