为什么这个异步函数在第一次尝试时返回空,但后来它 returns 一切?

Why is this async function returning empty on the first try, but then it returns everything?

我正在尝试将数据插入我的数据库,并且查询在映射循环内,所以我正在使用异步函数等待循环结束,并将所有结果存储在我的变量中“ practicasAgregadas.

我是这样调用函数的:

insertarPracticas(turno_id, req.body.lista_codigos_practicas, queryInsertarPracticas)
  .then(result => {
    res.status(200).json({
      "Practicas Agregadas": result
    })
  })

这是函数:

async function insertarPracticas(turno_id, req, queryInsertarPracticas) {
  const res = await Promise.all(req.map(r => {
    connection.query(
      queryInsertarPracticas, [turno_id, r], (error2, row2) => {
        if (error2) {
          console.log("Error al insertar turno detalle (prácticas): " + r + " " + error2);
          practicasNoAgregadas += r + "-";
        } else {
          console.log("Turnos detalle agregados " + r);
          practicasAgregadas += r + "-";
          console.log("practicas " + practicasAgregadas);
        }
      });
    return practicasAgregadas;
  })
  )

  console.log("en async " + res[0]);
  return res;
}

第一次尝试时,它 return 是空的:

这是控制台:

第二次尝试时,它确实 return,但它重复了 3 次:

和控制台:

大多数使用异步函数的现代 JS 库都会 return 承诺,但如果提供了回调,通常不会 return 承诺。

所以假设 connection.query 做了 return 一个承诺,那么下面的代码应该做你之后的事情..

async function insertarPracticas(turno_id, req, queryInsertarPracticas) {
    const res = await Promise.all(
        req.map(async (r) => {
            try {
                const row2 = await connection.query(queryInsertarPracticas, [
                    turno_id, r
                ]);
                console.log("Turnos detalle agregados " + r);
                practicasAgregadas += r + "-";
                console.log("practicas " + practicasAgregadas);
            } catch (e) {
                console.log(
                    "Error al insertar turno detalle (prácticas): " +
                        r + " " + error2
                );
                practicasNoAgregadas += r + "-";
            }
            return practicasAgregadas;
        })
    );

    console.log("en async " + res[0]);
    return res;
}

记住,不要使用回调,否则可能会向 lib 表明您不想要承诺 returning。

如果由于某种原因,lib 已经很长时间没有更新,您将需要 promisify 查询..

在 node 中,有一个名为 promisify https://nodejs.org/api/util.html#utilpromisifyoriginal 的实用工具可以让这一切变得更容易。

例如

const conQuery = util.promisify(connection.query);
const row2 = await conQuery(queryInsertarPracticas....

如果回调不是 (error, result) 形式,您将需要使用 Promise 构造函数.. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise,但查看您的代码 (error2, row2) => 不应该是必需的.