微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Node.js 中完成异步进程之前将 res 发送到客户端

如何解决在 Node.js 中完成异步进程之前将 res 发送到客户端

我有以下代码,在将响应发送回客户端之前,我无法弄清楚如何完成整个过程。它有一个 for 循环并向 2 个外部函数发出请求。

我在控制台中看到的问题是响应比进程完成处理所需的速度快得多。它让客户相信一切都很好,但是,实际上可能发生了一些错误。我试过等待,我试过阅读其他帖子,我试过让它返回一个承诺并返回一个解决方案,我试过一个索引来检查数组长度......如果有人可以帮助我,我会很感激。提前致谢。

var updateProdCharTree = async (req,res,next) => {
return new Promise((resolve,reject) => {
var data = req.body.raw.data;
var productLine = req.body.raw.productLine;
var bu = req.body.raw.bu;
let contErros = null;
let contAcertos = 0;

var maxId = 0;
let queryMaxId = `SELECT max(ProductCharFatherId) as maxId FROM maxiplastmatriz.productchar1 WHERE bu=${bu} and prodline=${productLine}`;
database.query(queryMaxId)
  .then(resultqueryMaxId => {
    if(resultqueryMaxId.length){
      maxId = resultqueryMaxId[0]['maxId'];
    }else{
      maxId = 0;
    }

    let queryAllNodes = `SELECT Id FROM productchar1 WHERE bu=${bu} and prodline=${productLine}`;
    database.query(queryAllNodes)
      .then( async resultqueryAllNodes => {

        for (let index = 0; index < data.children.length; index++) {
          const element = data.children[index];
          if (data.children[index].dbId != undefined) {
            let query = `SELECT Id FROM productchar1 WHERE bu=${bu} and prodline=${productLine} and Id=${data.children[index].dbId} and ProductCharFatherId=${data.children[index].id}`;
            database.query(query)
            .then( async result => {
                
              if (result.length) { // Update char in productchar1
                maxId++;
                var params = {element: element,productLine: productLine,bu: bu,index: index};
                waitResUp = await updateProductChar1(params,req,res); //***CALL EXTERNAL METHOD 2***
                contAcertos++;
              } else { // Add char in productchar1 shouldn´t get in here
                    console.log("Erro em: updateProdCharTree > addProductProductChar1");
                }
            
            })
            .catch(err => {
                console.log("Erro em query");
                contErros = 1;
            })
      
          }else{ // Add new char in productchar1
            maxId++;
            var params = {element: element,index: index,maxId: maxId};
            waitRes = await addProductProductChar1(params,res); //***CALL EXTERNAL METHOD 2***
            console.log("waitRes",waitRes.insertId);
            contAcertos++;
          }
        }
      })
      .catch(err => {
        console.log("Erro em queryAllNodes",err);
        contErros = 1;
      })

  })    
  .catch(err => {
    console.log("Erro em queryMaxId");
    contErros = 1;
  });

  if (contAcertos == data.children.length) {
    resolve("result"); // ***RES ATTEMPT***
  }

 })
 }

这里是初学者。请耐心等待。你曾经也是。

解决方法

对于初学者,您可以将代码重构为如下所示的内容,以便在执行循环中的所有异步函数后返回响应:


var updateProdCharTree = async (req,res,next) => {
  return new Promise((resolve,reject) => {
    var data = req.body.raw.data;
    var productLine = req.body.raw.productLine;
    var bu = req.body.raw.bu;
    let contErros = null;
    let contAcertos = 0;

    var maxId = 0;
    let queryMaxId = `SELECT max(ProductCharFatherId) as maxId FROM maxiplastmatriz.productchar1 WHERE bu=${bu} and prodline=${productLine}`;
    database
      .query(queryMaxId)
      .then((resultqueryMaxId) => {
        if (resultqueryMaxId.length) {
          maxId = resultqueryMaxId[0]["maxId"];
        } else {
          maxId = 0;
        }

        let queryAllNodes = `SELECT Id FROM productchar1 WHERE bu=${bu} and prodline=${productLine}`;
        database
          .query(queryAllNodes)
          .then(async (resultqueryAllNodes) => {
            return Promise.all(
              data.chilren.map(async (element) => {
                if (data.children[index].dbId != undefined) {
                  let query = `SELECT Id FROM productchar1 WHERE bu=${bu} and prodline=${productLine} and Id=${data.children[index].dbId} and ProductCharFatherId=${data.children[index].id}`;
                  let result = await database.query(query);

                  if (result.length) {
                    // Update char in productchar1
                    maxId++;
                    var params = {
                      element: element,productLine: productLine,bu: bu,index: index,};
                    waitResUp = await updateProductChar1(params,req,res); //***CALL EXTERNAL METHOD 2***
                    contAcertos++;
                  } else {
                    // Add char in productchar1 shouldn´t get in here
                    console.log(
                      "Erro em: updateProdCharTree > addProductProductChar1"
                    );
                  }
                } else {
                  // Add new char in productchar1
                  maxId++;
                  var params = {
                    element: element,maxId: maxId,};
                  waitRes = await addProductProductChar1(params,res); //***CALL EXTERNAL METHOD 2***
                  console.log("waitRes",waitRes.insertId);
                  contAcertos++;
                }
              })
            );
          })
          .then(() => {
            // This will be called after all queries are executed
            resolve("result");
          })
          .catch((err) => {
            console.log("Erro em queryAllNodes",err);
            contErros = 1;
            // NOTE: Ideally we should be rejecting promise in case of error
          });
      })
      .catch((err) => {
        console.log("Erro em queryMaxId");
        contErros = 1;
        // NOTE: Ideally we should be rejecting promise in case of error
      });
  });
};

正如@Jeremy Thille 建议的那样,可以进一步改进此代码,使其仅使用 async-await 而不是带有 then 回调的 Promises,从而使其更清晰易懂。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。