жду никогда не разрешать и следующая строка после этого никогда не выполняется - PullRequest
2 голосов
/ 23 сентября 2019

Я использую асинхронное ожидание, и мое ожидание никогда не разрешается, поэтому следующая строка не выполняется вообще.Под этим я подразумеваю эту строку:

result = await IndexingStatusResult(req, res);

в следующем коде:

router.post(
  "/api/result-store/v1/indexing-analyzer/:searchID/:id",
  async (req, res) => {
    console.log("Indexing started");
    var hrstart = process.hrtime();
    let result = null;

    result = await IndexingStatusResult(req, res);
    console.log("result is: ", result.data);
    hrend = process.hrtime(hrstart);
    console.info("Execution time (hr): %ds %dms", hrend[0], hrend[1] / 1000000);

    res.status(200).send({
      indexingTimeSec: hrend[0],
      indexingTimeMillSec: hrend[1] / 1000000
    });
  }
);

Но, как вы видите в IndexingStatusResult, я возвращаю обещание, когда все сделано:

const IndexingStatusResult = async (req, res) => {
  const docID = parseInt(req.params.id) * 1000;
  const dbName = "test_" + req.params.searchID;
  let result = null;
  try {
    result = await axios(
      `${params.HOST_NAME_WITH_PROTOCOL}/${dbName}/_design/searchAll/_search_info/searchAll`
    );
    result = result.data;
    console.log(
      "Number of docs indexed:",
      result.search_index.doc_count,
      "Total Docs needs to be indexed:",
      docID
    );
  } catch (e) {
    console.log(e);
  }
  console.log(`result returned is : ${JSON.stringify(result)}`);
  if (!result || parseInt(result.search_index.doc_count) < docID) {
return Promise.resolve(
  setTimeout(() => {
    console.log("WWWWWAAAAIIIIIITING");
    IndexingStatusResult(req, res);
  }, 5000)
);
  } else {
    console.log("YAAAAAAYYYYYYYYYYYYY");
    return Promise.resolve(result);
  }
};

Вот что я вижу:

Example app listening on port 3005!
Indexing started
Number of docs indexed: 0 Total Docs needs to be indexed: 5000
result returned is : {"name":"_design/searchAll/searchAll","search_index":{"pending_seq":0,"doc_del_count":0,"doc_count":0,"disk_size":0,"committed_seq":0}}
result is:  undefined
Execution time (hr): 0s 314.964402ms
WWWWWAAAAIIIIIITING
Number of docs indexed: 0 Total Docs needs to be indexed: 5000
result returned is : {"name":"_design/searchAll/searchAll","search_index":{"pending_seq":0,"doc_del_count":0,"doc_count":0,"disk_size":0,"committed_seq":0}}
WWWWWAAAAIIIIIITING
Number of docs indexed: 5001 Total Docs needs to be indexed: 5000
result returned is : {"name":"_design/searchAll/searchAll","search_index":{"pending_seq":5001,"doc_del_count":0,"doc_count":5001,"disk_size":797698,"committed_seq":0}}
YAAAAAAYYYYYYYYYYYYY

Таким образом, следующая строка никогда не выполняется:

console.log("result is: ", result.data);

Я что-то не так делаю?

1 Ответ

0 голосов
/ 23 сентября 2019

Несколько вопросов:

  • Вы пишете "Но, как вы видите в IndexingStatusResult Я возвращаю обещание, когда все сделано" .Это утверждение показывает неправильное представление: функция async возвращает обещание синхронно , а не когда "все" (асинхронно) выполнено.
  • "Мое ожидание никогда не разрешается [s]": Да, и раньше, чем вы думаете.Оператор console.log("result is: ", result.date) выполняет , но именно он вызывает ошибку.
  • Вызов setTimeout в IndexingStatusResult не задерживает момент разрешения обещаниячто он возвращается.Поскольку после вызова setTimeout вы ничего больше не делаете (при редактировании вы возвращаете здесь явно), обещание выполняется с undefined.На данном этапе обратный вызов setTimeout еще не выполнен.Значение разрешения undefined объясняет полученную ошибку.
  • Следует также отметить, что у вас уже было result = result.data, поэтому, даже если бы вы вернули это значение разрешения, result.data не существовало бы.
  • Вместо вызова setTimeout выполните await delay(5000), где delay возвращает обещание, которое разрешается после истечения времени ожидания.
  • В функции async вам не нужнооберните возвращаемое значение как обещание.Как указано выше, объект обещания уже был возвращен, и фактический оператор return должен указывать значение , с которым это обещание должно теперь разрешиться.

Итак (без тестирования)Я бы сказал, что этот код сделает работу лучше:

router.post(
  "/api/result-store/v1/indexing-analyzer/:searchID/:id",
  async (req, res) => {
    console.log("Indexing started");
    var hrstart = process.hrtime();
    let result = null;

    result = await IndexingStatusResult(req, res);
    console.log("result is: ", result); // not .data
    hrend = process.hrtime(hrstart);
    console.info("Execution time (hr): %ds %dms", hrend[0], hrend[1] / 1000000);

    res.status(200).send({
      indexingTimeSec: hrend[0],
      indexingTimeMillSec: hrend[1] / 1000000
    });
  }
);

// Helper function that's very useful in async functions:
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

const IndexingStatusResult = async (req, res) => {
  const docID = parseInt(req.params.id) * 1000;
  const dbName = "test_" + req.params.searchID;
  let result = null;
  while (true) {
    try {
      result = await axios(
        `${params.HOST_NAME_WITH_PROTOCOL}/${dbName}/_design/searchAll/_search_info/searchAll`
      );
      result = result.data;
      console.log(
         "Number of docs indexed:",
        result.search_index.doc_count,
        "Total Docs needs to be indexed:",
        docID
      );
    } catch (e) {
      console.log(e);
      return e; // ?? determine what you want to happen...
    } 
    console.log(`result returned is : ${JSON.stringify(result)}`);
    if (result && parseInt(result.search_index.doc_count) >= docID) break;
    await delay(5000); // delay and keep looping
  }
  console.log("YAAAAAAYYYYYYYYYYYYY");
  return result;
};
...