繁体   English   中英

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

现在,我有了这些数据的映射,需要在其中评估每个条目,并且想要创建一个数组,其中每个项目都包含每个条目的验证结果,并在完成所有操作后返回该数组。

所以像这样(简化):

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关键字,它将暂停一个函数,直到承诺已解决为止,因此我进行了更改,如下所示:

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

      InputDataMap.forEach(async(item) => {

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

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

您必须从validateEntry返回一个Promise:

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

then不需要仅返回其参数,并且不执行任何操作,因此可以删除.then(result => { return result; })

forEachasync回调不会使ValidateAll等待验证。 您必须等待所有Promises都解决,然后从ValidateAll返回Promise, forEach可以被map替换,因此您不需要手动执行推送:

let validationResults = new Array();

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

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

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

  return Promise.all(validationResults);
}

现在ValidateAll将返回一个Promise,该Promise将使用包含验证结果的数组进行解析。

您甚至可以将代码缩短为:

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

我读到,如果您使用async / await关键字,它将暂停一个函数,直到承诺已解决为止,因此我进行了更改,如下所示:

确实,它确实暂停了该函数,但是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})来使用它ValidateAll(inputData).then(results => {//Code})

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

您必须返回一个Promise,其中包含所有异步操作,如下所示:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM