Javascript асинхронное поведение с Mysql - PullRequest
2 голосов
/ 26 января 2020

Я очень озадачен асин c поведением JS.

У меня есть файл CSV, который содержит список URL, который необходимо удалить. И результат должен затем добавляться в базу данных строка за строкой в ​​течение l oop.

fs.readFile("./file.csv", async (err, data) => {
    if (err) {
      console.error(err);
      return;
    }
    let results = await neatCsv(data);
    db.connect();

    results.forEach(async row => {
      let ad = await kijiji.Ad.Get(row.url);
      let statement = "INSERT INTO Kijiji SET ?";

      let column = {
        uuid: uuid.v1(),
        url: ad.url,
        attributes: JSON.stringify(ad.attributes),
        latitude: ad.attributes.location.latitude,
        longitude: ad.attributes.location.longitude
      };
      const query = util.promisify(db.query).bind(db);
      await query(statement, column)
        .then()
        .catch(e => {
          throw e;
        });
    });

    const end = util.promisify(db.end).bind(db);
    await end()
      .then()
      .catch(e => {
        console.log(e);
        return failure({ status: e });
      });
});

Ожидаемое поведение для этого фрагмента кода должно быть синхронным, потому что, насколько я понимаю, await kijiji.Ad.Get(row.url); и await query(statement, column) ведут себя так, как если бы он был синхронным, потому что await заставляет программу ждать выполнения обещания.

Однако я получаю следующее сообщение об ошибке

Ошибка: невозможно enqueue Query после вызова quit. because await db.end () `вызывается первым.

Мой главный вопрос: как мне завершить соединение с БД без завершения соединения, прежде чем массив результатов l oop будет завершен?

Обновление: я преобразовал forEach в a для l oop, и вместо этого я использую массовую вставку

fs.readFile("./src/file.csv", async (err, data) => {
  if (err) {
    console.error(err);
    return;
  }
  let results = await neatCsv(data);
  db.connect();
  values = [];
  for (let i = 0; i < results.length; i++) {
    let row = results[i];
    console.log(count);
    count++;
    let ad = await kijiji.Ad.Get(row.url);
    console.log(ad);
    let column = [
      uuid.v1(),
      ad.url,
      JSON.stringify(ad.attributes),
      ad.attributes.location.latitude,
      ad.attributes.location.longitude
    ];
    values.push(column);
  }
  let statement =
    "INSERT INTO Kijiji (uuid, url, attributes, latitude, longitude) SET ?";

  const query = util.promisify(db.query).bind(db);
  await query(statement, values)
    .then()
    .catch(e => {
      throw e;
    });
  db.end();
});

Но выполнение выполняется очень медленно, возможно, около 1-2 секунд на URL, когда foreach занимал около нескольких миллисекунд. Почему это?

...