JavaScript 服务器调用 - 等待承诺

JavaScript Server Call - Wait for Promise

我正在编写服务器调用来填充地图。我似乎无法获得正确的代码,知道它将在何处等待,直到服务器调用完成,然后再继续。我编写了以下函数 DoIt,它调用调用服务器并填充地图的 someTimeConsumingthing。它将在 SomeTimeConsumingThing 中执行服务器调用,但是它随后会跳出该函数并转到下一个代码块。

export function onBeforePriceRules(quote, lineModels, conn) {
  var varQuoteHostid;

  if (lineModels.length) {
    var varProdIds = [];
    //Might want to do a function here.
    lineModels.forEach(function (line) {
      varQuoteHostid = quote.record["Host__c"];
      var varProdId = line.record["SBQQ__Product__c"];
      if (varProdId) {
        varProdIds.push(varProdId);
      }
    });
  }

  const UniqueProdList = [...new Set(varProdIds)];
  var ProdIdList = "('" + UniqueProdList.join("', '") + "')";

  let myMap;
  var ProductMap = new Map();

  //Call DoIt
  doit(conn, ProdIdList, ProductMap).then(function () {
    console.log("Now finally done!");
    debugger;
  });

  var NewVarable = "NewThing";
  console.log("NewVarable" + NewVarable);
  debugger;

  return Promise.resolve();
}

function someTimeConsumingThing(conn, ProdIdList, ProductMap) {
  console.log("someTimeConsumingThing");
  debugger;

  conn
    .query("SELECT Id, Model__c FROM Product2 WHERE ID IN" + ProdIdList)
    .then(async function (returnedRecords) {
      if (returnedRecords.totalSize) {
        returnedRecords.records.forEach(function (record) {
          ProductMap.set(record.Id, record);
          console.log("ProductMap" + ProductMap);
          debugger;
        });
      }
    });
   return ProductMap;
}
async function doit(conn, ProdIdList, ProductMap) {
  console.log("Calling someTimeConsumingThing");
  debugger;
  await someTimeConsumingThing(conn, ProdIdList, ProductMap);
  console.log("Ready with someTimeConsumingThing");
  debugger;
}

当您使用

时,您正在创建一个承诺
  conn
  .query("SELECT Id, Model__c FROM Product2 WHERE ID IN" + ProdIdList)

并且您通过调用 then 来扩展该承诺,字面意思是在承诺解决后做一些事情。问题是你不是在任何地方等待那个承诺,而是你在那之后立即创建一个新的承诺,你 return 和 awaitdoit 函数中。

  return new Promise(function (resolve, reject) {
    setTimeout(resolve, 2000);
  });

你想要的是等待实际的查询承诺,所以将你的 someTimeConsumingThing 编辑为 return 查询承诺,就像这样

function someTimeConsumingThing(conn, ProdIdList, ProductMap) {
  console.log("someTimeConsumingThing");
  debugger;
  
  // Imagine this as a block, that executes some time somewhere.
  // Everything outside of it gets executed when you call this function
  return conn
    .query("SELECT Id, Model__c FROM Product2 WHERE ID IN" + ProdIdList)
    .then(async function (returnedRecords) {
      if (returnedRecords.totalSize) {
        returnedRecords.records.forEach(function (record) {
          ProductMap.set(record.Id, record);
          console.log("ProductMap" + ProductMap);
          debugger;
        });
      }
    });
  }

与 async/await 语法相同

async function someTimeConsumingThing(conn, ProdIdList, ProductMap) {
  console.log("someTimeConsumingThing");
  debugger;
  
  // Await for the query results
  const returnedRecords = await conn
    .query("SELECT Id, Model__c FROM Product2 WHERE ID IN" + ProdIdList)

  if (returnedRecords.totalSize) {
    returnedRecords.records.forEach(function (record) {
      ProductMap.set(record.Id, record);
      console.log("ProductMap" + ProductMap);
      debugger;
    });
  }
  return whateveryouwant
}

阅读更多关于承诺 here 并且不要害怕 google 它们是如何工作的 and/or 对它们的解释!