【问题标题】:Wait for nodeJs async/promise process to end before sending response to client在向客户端发送响应之前等待 nodeJs async/promise 进程结束
【发布时间】:2018-11-13 15:31:18
【问题描述】:

我有以下代码,在将响应发送回客户端之前,我无法弄清楚我需要做什么才能完成整个过程。基本上,我正在寻找客户端在方法中的所有内容完成或出错后收到响应,而不是之前。

我尝试了几件事,移动了一些东西并添加了一些甚至可能不需要的 .then() 和 .catch() 块。我对 NodeJs 还很陌生,所以虽然我了解事情是如何工作的,但我仍然不习惯异步编码。

let markStepsComplete = async function() {

let stepsToProcess = new Multimap();//multimap JS npm
let results = await dbUtils.getCompletedSteps();
results.forEach(result => {
    stepsToProcess.set(result.ticket_id, result.step_id);
});
return new Promise((resolve,reject)=>{
    stepsToProcess.forEachEntry(async function(entry, key) {
        let payload = {
            ticketId: key,
            stepIds: entry
        }
        let response = await updateStep(payload)//returns promise
            if (response.statusCode === 200) {
                await Promise.all(payload.stepIds.map(async (stepId) => {
                    try {
                        await dbUtils.markStepsCompleted(stepId, payload.ticketId);
                    } catch(err) {
                        reject(err);
                    }
                }));
            }
            else {
                await Promise.all(payload.stepIds.map(async (stepId) => {
                try {
                    await dbUtils.markStepsProcessed(stepId, payload.ticketId, response.statusCode);
                } catch(err) {
                    console.log(err);
                    reject(err);    
                }
                }));

            }


    });
    resolve('Steps Marked Complete');  


});//promise end



}

这是我现在正在测试的调用上述方法的路径。 updateStep() 方法是实际调用外部 REST API 的 HTTP 请求的方法。这似乎正在兑现承诺。

app.use('/api/posts',async (req,res,next)=>{

let data = await markStepsComplete.markStepsComplete()
.then((data)=>{
    res.status(200).json({message: data})
})
.catch((e)=>{
    console.log('error from catch:',e);
})

})

作为此过程的一部分,上面的代码运行并且确实在我们的数据库中运行了一些东西,但是在过程完成之前我收到了“步骤标记完成”解析消息。 由于解析是在流程结束之前完成的,因此我永远无法将任何拒绝()错误返回给客户端,因为已经调用了解析。

提前致谢。

【问题讨论】:

  • 我不清楚您为什么同时使用 async/await 语法 调用 .then() 等;前者通常取代后者。我不确定这是否会产生影响,但这对我来说是一个标志,你正在做这两个,我不希望它们起作用。
  • 是的,我只是想添加一些东西来看看它是否会起作用。它最初没有 .then()s。但是我上面的这个版本是我得到的最接近的版本,因为当我在客户端执行该过程时,它确实会等待几秒钟才能发回该消息……而最初它会立即将其发回。

标签: node.js express


【解决方案1】:

我注意到这个 sn-p 并想把它叫出来,因为它不起作用:

payload.stepIds.forEach(async (stepId) => {
  try {
    await dbUtils.markStepsProcessed(stepId, payload.ticketId, response.statusCode);
  } catch(err) {
    console.log(err);
    reject(err);    
  }
});

在遍历需要异步获取的项目数组时,您可以执行以下操作:

await Promise.all(payload.stepIds.map(async (stepId) => {
  try {
    await dbUtils.markStepsProcessed(stepId, payload.ticketId, response.statusCode);
  } catch(err) {
    console.log(err);
    reject(err);    
  }
}));

【讨论】:

  • 感谢您的回复。我已经实施了您的解决方案,但它似乎并没有对我正在寻找的东西产生影响。我想知道我是否需要最初使用通用的 Promise.all() 方法来确保在发送回客户端之前解决/拒绝所有承诺。因为我有这么多的功能/承诺。
  • 是的....任何有forEach 的东西也需要像上面的方法一样循环处理异步请求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-19
  • 2019-02-07
  • 2020-02-29
  • 1970-01-01
  • 2022-11-04
  • 2014-10-01
  • 1970-01-01
相关资源
最近更新 更多