为什么使用了await却执行了function?
Why function is executed although await is used?
我在主函数中使用了 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
不要直接在 async
函数中使用 setTimeout
。相反,使用基于 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 );
});
}
- 然后你可以用“真正的”
while
循环重写你的 poll
函数,如下所示。
- 我认为你的
poll
函数应该 return 一个 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
而不是在其中包含更多逻辑,因为通常您不想捕获不相关的错误.
使用 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();
我在主函数中使用了 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
不要直接在 async
函数中使用 setTimeout
。相反,使用基于 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 );
});
}
- 然后你可以用“真正的”
while
循环重写你的poll
函数,如下所示。 - 我认为你的
poll
函数应该 return 一个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
而不是在其中包含更多逻辑,因为通常您不想捕获不相关的错误.
使用 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();