节点同步循环

时间:2019-03-27 15:26:39

标签: node.js loops asynchronous

我有一个功能。

function async extractTars (tarList) {
  try {
    for (let i = 0; i < tarList.length; i ++) {
      // I need this loop to be sync but it isn't hitting the next iteration
      return new Promise((resolve, reject) => {
        fs.createReadStream(`${PATHS.TAR}/${tarList[i]}`)
          .pipe(tar.extract(PATHS.GZ))
          .on('error', err => reject(err))
          .on('finish', () => resolve())
      })
    }
    // What is the correct way to resolve this async fn? Should i just return or will it resolve anyway after the loop?
  } catch (e) {
    // handle error
  }
}

由于某种原因,它永远不会到达循环的下一个迭代。我在这里想念什么?我如何才能使这些类型的循环同步。在这个特定的项目中,我有很多循环需要在下一个循环之前完成。我已经尝试过几种在SO上看到过的方法,但是我显然缺少了一些东西。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:2)

您使用的是return,这就是为什么您不执行下一个迭代,而是使用await等到诺言完成后再进行下一个迭代。

return内的

for将停止循环并结束函数返回new Promise

function async extractTars (tarList) {
  try {
    for (let i = 0; i < tarList.length; i ++) {
      // I need this loop to be sync but it isn't hitting the next iteration
      await new Promise((resolve, reject) => {
        fs.createReadStream(`${PATHS.TAR}/${tarList[i]}`)
          .pipe(tar.extract(PATHS.GZ))
          .on('error', err => reject(err))
          .on('finish', () => resolve())
      })
    }
    // What is the correct way to resolve this async fn? Should i just return or will it resolve anyway after the loop?
  } catch (e) {
    // handle error
  }
}

只是为了清除问题:

  

我需要此循环进行同步,但不会遇到下一个迭代

使用async/await时,该循环将不会同步,看起来就像是同步,但是您无法使异步代码同步。 createReadStream是不同步的。

关于:

  

解决此异步fn的正确方法是什么?我应该   返回,还是循环后仍能解决?

当所有迭代完成或引发错误(因为您正在捕获它且未拒绝)时,这意味着您读取了tarList中的所有文件,该函数将被解析。由于您未返回任何内容,因此undefined将成为解析后的值。

来自MDN

  

在函数主体中使用 return 语句时,该函数的执行将停止。如果指定,给定值将返回给函数调用者。例如,以下函数返回其参数x的平方,其中x是数字。