async.js 使用 async / await - 需要帮助解释为什么这不起作用
async.js with async / await - need help explaining why this doesn't work
我目前正在使用支持 ES2017 异步的 async.js v2.3.0。
我想弄清楚为什么 doSomething
的 returns 承诺在 IIEF 中有效,但 doSomething2
未得到遵守。是因为 doSoomething2
是一个异步函数但不完全是 运行 “异步”代码吗?我觉得我在这里错过了什么。
function promiseTimeOut() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(20);
}, 1000);
})
}
function doSomething() {
return new Promise((resolve, reject) => {
async.retry({
times: 5,
interval:(retryCount)=>{ return 50 * Math.pow(2, retryCount); }
}, async () => {
return await promiseTimeOut();
}, (err, result) => {
resolve(result);
});
})
}
async function doSomething2() {
async.retry({
times: 5,
interval:(retryCount)=>{ return 50 * Math.pow(2, retryCount); }
}, async () => {
return await promiseTimeOut();
}, (err, result) => {
return result;
});
}
// main function
(async () => {
async.series([
(callback) => {
callback(null, 1);
},
async () => {
return await doSomething();
},
async () => {
// doesn't get waited on, returns undefined right away
return await doSomething2();
}
], (err, result) => {
// result: 1, 20, undefined
console.log(result);
});
})()
您正在以回调方式编写 async.retry,这样它就不会等到完成。尝试console.log(result)
,你可以看到
[ 1, 20, undefined ]
20
查看 retry
的文档,以及其他方法,它引用了
Returns:
a promise if no callback provided
所以你只需要立即return而不提供任何回调
async function doSomething2() {
return async.retry(
{
times: 5,
interval: (retryCount) => {
return 50 * Math.pow(2, retryCount)
},
},
async () => {
return await promiseTimeOut()
}
)
}
Async.js 正在对您的代码执行反编译以根据您使用的是异步函数(return 承诺)还是基于回调的函数来调整其行为。这就是为什么你会看到不同的行为,它只取决于一个简单的事实,即在你的函数前面是否有一个“async”关键字(即使行为应该是相同的) .
坦率地说,这不是一个好主意。 Async.js 做的还不错,但显然是一个库,它是为简化回调的使用而构建的,后来升级为尝试使用 promises。不幸的是,这种基于反编译的自动魔术行为可能而且将会导致问题。例如,它可以使代码的行为完全不同,具体取决于您是否使用像 Babel 这样的预编译器。
我最近发布了一个库,它是 async.js 的替代品,它专门用于仅使用 Promises(和 async/await),从而使一个完全一致的库可以使用那些更新的工具。
结果名为 modern-async,位于此处:https://nicolas-van.github.io/modern-async/
我目前正在使用支持 ES2017 异步的 async.js v2.3.0。
我想弄清楚为什么 doSomething
的 returns 承诺在 IIEF 中有效,但 doSomething2
未得到遵守。是因为 doSoomething2
是一个异步函数但不完全是 运行 “异步”代码吗?我觉得我在这里错过了什么。
function promiseTimeOut() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(20);
}, 1000);
})
}
function doSomething() {
return new Promise((resolve, reject) => {
async.retry({
times: 5,
interval:(retryCount)=>{ return 50 * Math.pow(2, retryCount); }
}, async () => {
return await promiseTimeOut();
}, (err, result) => {
resolve(result);
});
})
}
async function doSomething2() {
async.retry({
times: 5,
interval:(retryCount)=>{ return 50 * Math.pow(2, retryCount); }
}, async () => {
return await promiseTimeOut();
}, (err, result) => {
return result;
});
}
// main function
(async () => {
async.series([
(callback) => {
callback(null, 1);
},
async () => {
return await doSomething();
},
async () => {
// doesn't get waited on, returns undefined right away
return await doSomething2();
}
], (err, result) => {
// result: 1, 20, undefined
console.log(result);
});
})()
您正在以回调方式编写 async.retry,这样它就不会等到完成。尝试console.log(result)
,你可以看到
[ 1, 20, undefined ]
20
查看 retry
的文档,以及其他方法,它引用了
Returns: a promise if no callback provided
所以你只需要立即return而不提供任何回调
async function doSomething2() {
return async.retry(
{
times: 5,
interval: (retryCount) => {
return 50 * Math.pow(2, retryCount)
},
},
async () => {
return await promiseTimeOut()
}
)
}
Async.js 正在对您的代码执行反编译以根据您使用的是异步函数(return 承诺)还是基于回调的函数来调整其行为。这就是为什么你会看到不同的行为,它只取决于一个简单的事实,即在你的函数前面是否有一个“async”关键字(即使行为应该是相同的) .
坦率地说,这不是一个好主意。 Async.js 做的还不错,但显然是一个库,它是为简化回调的使用而构建的,后来升级为尝试使用 promises。不幸的是,这种基于反编译的自动魔术行为可能而且将会导致问题。例如,它可以使代码的行为完全不同,具体取决于您是否使用像 Babel 这样的预编译器。
我最近发布了一个库,它是 async.js 的替代品,它专门用于仅使用 Promises(和 async/await),从而使一个完全一致的库可以使用那些更新的工具。
结果名为 modern-async,位于此处:https://nicolas-van.github.io/modern-async/