【问题标题】:Problem with for-of loop and async function [duplicate]for-of循环和异步函数的问题[重复]
【发布时间】:2020-12-08 00:02:53
【问题描述】:

我想等到我的函数 checkNumber() 完成并返回结果。不幸的是 for-off 循环不会等待函数并在开始时进行所有迭代。我尝试了许多与 async/await 的组合,但没有一个真正起作用。当我运行这个函数时,它会打印出与循环一样多的 console.log("start error"),然后我得到 productList。当 checkNumber() 返回错误时,我想停止 for 循环。

主要功能:

  if (!req.body) {
    res.status(400).send({
      message: "Values can not be empty!"
    });
  }

  console.log("list of products: ", req.body.product);
  const productArr = req.body.product; //array of products retrieved from json
  let productList = [];
  let quantityList = [];
  let error = 0;
  for (const product of productArr) { //iterate through products

    console.log("start error: ", error); // <---- 
    if (error == 1) {
      console.log("stop");
      break;
    }

    //check if product's vat exists in vat table, if not add new
    Vat.checkNumber(product.vat, async function (err, data) {
      console.log("result: ", data);
      if (!data) {
        console.log("not found");
        console.log(err);
        error = 1;
      } else {
        console.log("found");
        const vat_id = data;

        //crete new product obj json
        let newProduct = {
          vat_id: vat_id,
          name: product.name,
          price: product.price
        };

        //store product list and their quantity to use later in sql query
        productList.push(newProduct);
        quantityList.push(product.quantity);
        console.log(productList);
        console.log(quantityList);


      }
    });
  }
}

增值税功能:

  sql.query("SELECT * FROM vat where number = ?", number, function (err, res) {
    if (err) {
      console.log("error: ", err);
      result(err, null);
      return;
    }

    if (res.length <= 0) {
      err = "Vat cannot be null";
      result({ error: "Vat not found" }, null);
      return;
    }

    console.log("Found vat: ", res[0].id);
    result(null, res[0].id);
    return;
  });
};

【问题讨论】:

  • 你应该“承诺”你的增值税函数,然后在循环中等待它。现在你正在开火而忘记。
  • 你的意思是把vat函数包装在promise中吗?
  • 是的,请参阅下面的答案。
  • 我应该澄清一下,您并没有真正触发并忘记,而是您的 Vat.checkNumber 调用的回调函数不是 await:ed 在循环中。
  • 好吧。现在我明白了。但是在您的回答中,您跳过了第二个参数 **Vat.checkNumber = function (number, result) { ** result.我可以像你一样跳过这个结果吗?你能给我解释一下吗?我对回调有点困惑。

标签: javascript node.js express asynchronous


【解决方案1】:

试试这个:

async function checkNumber(number) {
  return new Promise((resolve, reject) => {
    sql.query('SELECT * FROM vat where number = ?', number, function(err, res) {
      if (err) {
        console.log('error: ', err);
        reject(err);
        return;
      }

      if (res.length <= 0) {
        err = 'Vat cannot be null';
        reject({ error: 'Vat not found' });
        return;
      }

      console.log('Found vat: ', res[0].id);
      resolve(res[0].id);
    });
  });
}

然后

for (const product of productArr) { //iterate through products

  console.log("start error: ", error); // <---- 
  if (error == 1) {
    console.log("stop");
    break;
  }

  //check if product's vat exists in vat table, if not add new
  let data; 
  try {
    data = await checkNumberPromisified(product.vat);
    if (!data) {
      console.log("not found");
      error = 1;
    } else {
      console.log("found");
      const vat_id = data;

      //crete new product obj json
      let newProduct = {
        vat_id: vat_id,
        name: product.name,
        price: product.price
      };

      //store product list and their quantity to use later in sql query
      productList.push(newProduct);
      quantityList.push(product.quantity);
      console.log(productList);
      console.log(quantityList);
    }
  }
  catch (err) {
    console.log(err);
    error = 1;
  }
}

【讨论】:

  • 抛出错误; // 重新抛出非 MySQL 错误 ^ TypeError: result is not a function
  • 就像我说的,你跳过了结果函数,所以现在我应该将它折射并从函数参数中删除,确定吗?
  • 我将答案更改为手动承诺 checkNumber 函数。希望对您有所帮助。
  • 添加了异步功能,现在它可以工作了。所以现在我什至不需要 if (!data),因为如果发生错误,它会直接捕获,对吧?
  • 感谢您的帮助。它让我感到困惑,因为它可以在没有像 checkNumber() 那样在 promise 中包装函数的情况下工作。是 util.promisify 为我们做的,所以我们不需要手动做吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-07
  • 1970-01-01
  • 2014-03-03
  • 2020-11-16
  • 2020-04-20
  • 1970-01-01
相关资源
最近更新 更多