JS async/await 不等待我的函数解决它们的承诺

JS async/await doesn't wait for my functions to resolve their promise

你能帮我理解为什么这不起作用吗:

我在 Aurelia 工作,我尝试使用验证控制器验证一些输入数据,记录在此处:https://aurelia.io/docs/plugins/validation#validation-controller

现在,我有这个数据的地图,我需要在其中评估每个条目,我想创建一个数组,其中每个项目包含每个条目的验证结果,当一切都完成后,return数组。

所以像这样(简化):

function ValidateAll(InputDataMap){
  let validationResults = new Array();

  InputDataMap.forEach((item) => {
     validationResults.push(validateEntry(item));
  });

 return validationResults;
}

function validateEntry(item){

(aurelia's validation)controller.validate(item, "some value", "some rule")
      .then(result => {
        return result;
      });
}

现在,这当然行不通,因为我需要等待验证控制器解决它的承诺,然后才能取回任何数据,到目前为止,我在这方面失败了。

我读到如果你使用 async/await 关键字,它会暂停一个函数,直到 promise 被解决,所以我做了一些改变,像这样:

function ValidateAll(InputDataMap){
      let validationResults = new Array();

      InputDataMap.forEach(async(item) => {

         let result = await validateEntry(item);
         validationResults.push(result);
});

现在,这也不起作用,这就是我想知道的。我想我的 "validateEntry" 函数一旦成为 运行 就被 "await" 认为已完成,并且不会等待 "validateEntry" 中的 "validate()" 函数的承诺成为解决。我可以像这样简单地编写它并进行一些修改并且仍然可以正常工作吗?

I read that if you use the async/await keyword it will pause a function until the promise has been resolved, so I made changes, something like this:

确实它确实暂停了函数,但是async(item) => {//Code}是另一个不受外部函数影响的函数

async function ValidateAll(InputDataMap){
      let validationResults = [];
      for (item of InputDataMap) {
          let result = await validateEntry(item);
          validationResults.push(result);
      }
      return validationResults;      
});

还要注意函数声明前面的 async 关键字,这意味着您必须通过 let results = await ValidateAll(inputData) 或类似 ValidateAll(inputData).then(results => {//Code})

来使用它
function ValidateAll(InputDataMap){
      return Promise.all(InputDataMap.map(item => validateEntry(item)))
});

您必须 return 来自您 validateEntry 的承诺:

function validateEntry(item){
  return controller.validate(item, "some value", "some rule")
}

一个then只是return它的参数不是必需的,什么都不做,所以.then(result => { return result; })可以被删除。

forEachasync 回调不会使 ValidateAll 等待验证。你必须等待所有的 Promise 被解决,并且 return 来自 ValidateAll 的 Promise,forEach 可以被 map 代替,这样你就不需要做手动推送:

let validationResults = new Array();

validationResults = InputDataMap.map(item => validateEntry(item));

这里不需要async,因为这里不需要await。现在 validationResults 包含一个 Promises 列表。您现在需要使用 Promise.all 等待这些问题得到解决。

function ValidateAll(InputDataMap){
  let validationResults = InputDataMap.map(item => validateEntry(item));

  return Promise.all(validationResults);
}

现在 ValidateAll 将 return 一个将使用包含验证结果的数组解析的 Promise。

您可以将代码进一步缩短为:

function ValidateAll(InputDataMap){
  return Promise.all( InputDataMap.map(validateEntry) );
}

你必须 return 一个包含所有异步操作的 Promise,像这样:

function ValidateAll(InputDataMap) {
  return Promise.all(InputDataMap.map(item => validateEntry(item)));
}