簡體   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