javascript - 按顺序从嵌套循环执行异步处理函数

标签 javascript node.js

我有一个功能可以在数据库中保存大量数据。最后会异步调用回调。

function process(..., fn) {
  saveInDB(function(err, results) {
    // ...
    // fn() or fn(err)
  })
}

该函数在嵌套循环中被多次调用。

for (const x of arrays) {
  const space1 = x[0]
  for (const y of x.slice(1)) {
    const space2 = y[0]
    for (const z of y[1]) {
      process(space1, space2, z, fn)
    }
  }
}

该问题要求仅当上一次调用成功时才会发生下一次调用。这是我繁琐的实现。

let calls = []
for (const x of arrays) {
  const space1 = x[0]
  for (const y of x.slice(1)) {
    const space2 = y[0]
    for (const z of y[1]) {
      calls.push((fn) => () => process(space1, space2, z, fn))
    }
  }
}

let call = null

for (let i = calls.length - 1; i >= 0; --i) {

  if (i === calls.length - 1) {
    call = calls[i](err => {
      if (!err)
        return finalCallback(null, { 'status': 'success' })
      log.error(err)
      finalCallback(err)
    })
    continue
  }

  const lastNext = call
  call = calls[i](err => {
    if (!err)
      return lastNext()
    finalCallback(err)
    log.error(err)
  })
}

if (call)
  call()

我正在寻求 Javascript 专业人士的建议,你们如何解决此类问题?

最佳答案

使用async ...await

在您的用例中,使用 await 关键字将允许您等待 process 返回的 promise 在继续之前解决。您必须将函数定义为async

您还需要使用 try ... catch block 来处理任何错误。

由于您的 process 函数当前未返回 Promise,因此您需要对其进行修改才能执行此操作。

示例:

function process(/* your args */) {
  return new Promise((resolve, reject) => {
    saveInDB((err, results) => {
      if (err) {
        reject(err)
      } else {
        resolve(results)
      }
  })
}

// now for the `async ... await`
async function myFunc(arrays) {
  for (const x of arrays) {
    const space1 = x[0]
    for (const y of x.slice(1)) {
      const space2 = y[0]
      for (const z of y[1]) {
        try {
          // This will wait until your `process` has finished
          await process(space1, space2, z, fn)
        } catch (error) {
          // handle any errors
          console.log(error)
          // if you would like to bail after an error you can `return`
          return
        }
      }
    }
  }
}

现在您的函数已经存在,您可以使用它,但是,它是异步的,因此它不会停止运行之后的任何代码,因此您应该执行以下两件事之一:

  1. await 您对 myFunc 的调用或
  2. 将任何依赖于 saveInDB 的代码首先放在 .then()
myFunc(/* your arrays */)
  .then(() => {
    // your function has finished
  })

关于javascript - 按顺序从嵌套循环执行异步处理函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55287288/

相关文章:

node.js - 加速 AngularJs 项目的 Travis-CI 依赖项安装

javascript - 如何逐行读取文件中的行并检查行是否为空?

node.js - Gulp - gulp 可以在没有 Node 的情况下使用吗?

javascript - 当我只想要一个时,克隆会复制多次

javascript - 滚动时尝试使用 jquery 使内容淡入

javascript - 如何将 p5.js Canvas 放置在 div 容器内?

javascript - 将 "with (...) {...}"中的关键文字声明到其中运行的沙箱代码是否安全?

javascript - 如果用户停止滚动超过 1 秒,使导航栏返回焦点

python - 通过Python或Node访问GKE kubectl

javascript - 如何只在数据推送完成时才执行回调?