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/