阻止js中的异步功能?

时间:2020-08-17 06:24:35

标签: javascript node.js promise

我有一个用于长时间运行异步操作的构建器,并且我需要这些操作中的每一个都可以运行阻塞,任何时候都应该只运行一个任务。

在代码示例中,我希望test等待直到解决了所有内部等待,然后才解决test函数本身,从而使代码可以继续执行下一个任务。

;(async () => {

  const after = (time) => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve()
      }, time)
    })
  }

  const test = async (item) => {
    console.log("running item", item)
    await after(100)
    console.log("running step 1 item", item)
    await after(100)
    console.log("running step 2 item", item)
    await after(100)
    console.log("running step 3 item", item)
    await after(100)
    console.log("running step 4 item", item)
  }
  
  console.log("running")
  const promises = [1,2,3,4,5].map((item) => {
    return () => {
      test(item)
    }
  })
  for (const promise of promises) {
    console.log('running promise', promise)
    await promise()
  }

})()

此刻,当每个 UnhandledPromiseRejectionWarning: TypeError: promise is not a function调用都允许运行另一个await任务时,此代码给我一个异常test,并且还并行运行所有测试功能。这是根据规范,但不是我需要的。

这是当前的输出,显示执行在项目上进行迭代,而我希望item 1item 2之前得到完全处理

running
running item 1
running item 2
running item 3
running item 4
running item 5
running step 1 item 1
running step 1 item 2
running step 1 item 3
running step 1 item 4
running step 1 item 5
running step 2 item 1
running step 2 item 2
running step 2 item 3
running step 2 item 4
running step 2 item 5
running step 3 item 1
running step 3 item 2
running step 3 item 3
running step 3 item 4
running step 3 item 5
running step 4 item 1
running step 4 item 2
running step 4 item 3
running step 4 item 4
running step 4 item 5

解决方案: 关键不是创建所有诺言,而是等待每个诺言完成,然后再创建下一个诺言。有效的代码:

;(async () => {
  const after = (time) => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve()
      }, time)
    })
  }

  const test = async (item) => {
    console.log("running item", item)
    await after(100)
    console.log("running step 1 item", item)
    await after(100)
    console.log("running step 2 item", item)
    await after(100)
    console.log("running step 3 item", item)
    await after(100)
    console.log("running step 4 item", item)
  }

  console.log("running")
  const promises = [1, 2, 3, 4, 5].map((item) => {
    return async () => {
      await test(item)
    }
  })
  for (const promise of promises) {
    await promise()
  }
})()

2 个答案:

答案 0 :(得分:0)

当前,您正在一次构建所有的承诺。您只希望在完成前一个承诺时构造一个承诺:

import shap
explainer = shap.TreeExplainer(rf)
shap_values = explainer.shap_values(X_test)
shap.summary_plot(shap_values, X_test, plot_type="bar")

或者,您可以构建一个承诺链:

for (let i = 1; i <= 5; i++) {
    await test(i);
}

这等效于:

const p = [1, 2, 3, 4, 5].reduce((p, i) => p.then(() => test(i)), Promise.resolve())
await p;

答案 1 :(得分:-1)

如果您希望5个调用同时进行测试,则说明您在正确的轨道上,并且您可能希望研究Promise.all来进行一些清理。如果您希望5个测试调用依次执行,那么循环执行并等待每个调用可能会更容易。