javascript - 等待永远不会解决,之后的下一行从未执行

标签 javascript node.js ecmascript-6 promise async-await

我正在使用 async await 并且我的 await 从未解析,所以下一行根本没有执行。我的意思是这一行:

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 中看到的那样,当一切都完成时我返回一个 promise :

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);

我做错了什么吗?

最佳答案

几个问题:

  • 你写“但是正如你在IndexingStatusResult中看到的那样,当一切都完成时,我会做出 promise ”。此声明显示了一个误解:An async函数返回一个 promise 同步,而不是在“一切”(异步)完成时。
  • “我的 await 永远不会解决 [s]”:它会解决,而且比您想象的要快。声明console.log("result is: ", result.date) 确实被执行,但它是触发错误的那个。
  • 来电setTimeoutIndexingStatusResult不会延迟它返回的 promise 的解决时刻。在调用 setTimeout 之后您什么都不做(在编辑中,您在此处显式返回), promise 以 undefined 实现. 现阶段setTimeout回调尚未执行。 undefined分辨率值解释了您遇到的错误。
  • 还应注意,您已经拥有 result = result.data ,所以即使您将其作为分辨率值返回,result.data不会存在。
  • 而不是 setTimeout打电话,做await delay(5000) , 其中delay返回超时后解决的 promise 。
  • async函数,您不需要将返回值包装为 promise 。如上所述,promise 对象已经返回,实际的 return语句应指示该 promise 现在应解决的

所以(没有测试),我会说这段代码会做得更好:

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;
};

关于javascript - 等待永远不会解决,之后的下一行从未执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58066392/

相关文章:

javascript - Titanium.Network.online 无法在 Android 模拟器上运行

javascript - promise 所有并获得请求

node.js - Node/Express 是否重新定义了 request.ip?

javascript - 如何计算按钮点击次数

javascript - Q 库版本 0.9.7 promise 与 ES2015 promise 兼容吗?

javascript - Array.reduce() 按对象字段分组并将所有其他字段扩展到其相应的分组对象字段

javascript - 如何用一个对象的值覆盖另一个对象的值 (lodash)

javascript - 除非调整屏幕大小,否则悬停时的滚动功能将不起作用

javascript - 如何在 TypeScript 中正确引用模块?

node.js - 从正则表达式中提取负值