簡體   English   中英

JavaScript:如何在for循環中從Asyn函數返回值

[英]JavaScript: how to return a value from a asyn function in a for loop

我得到了一個服務,如下所示返回一個值:

// Service.js
var done = false;
var readyToSubmit = function(answerArr, len) {
  var threshold = 0;
  for (var i = 0; i < answerArr.length; i++) {
    var id = answerArr[i].focus + '_' + userData.uid;
    appStore.getDoc(id).then(function(doc) {
      if (doc.doneRate == 100) {
        threshold++;
        if (threshold == len) {
          done = true;
        } else {
          done = false;
        }
      }
    });
  }
  return done; // here, It always returns 'undefined'.
};

我想在我的AngularJs項目中使用此服務,如下所示:

var answerArr = $scope.homework.items;
var len = answerArr.length;
$scope.$on('appChange', function(e, doc) {
  $scope.done = hwService.readyToSubmit(answerArr, len);
});

但是,總是沒有運氣,盡管我嘗試調用readyToSubmit(para1, para2, callback) ,但這種調用不會帶來任何readyToSubmit(para1, para2, callback) 這真的使我煩了大約4個小時。 所以有人想在這里幫我一個忙嗎? 非常感謝~~ :)

您不能使用這樣的異步函數。

您可以使用角度承諾來實現這一目標。

// Service.js
var done = false;
var defered = $q.defer() //include in service function $q
var readyToSubmit = function(answerArr, len) {
  var threshold = 0;
  for (var i = 0; i < answerArr.length; i++) {
    var id = answerArr[i].focus + '_' + userData.uid;
    appStore.getDoc(id).then(function(doc) {
      if (doc.doneRate == 100) {
        threshold++;
        if (threshold == len) {
          defered.resolve(true);
        } else {
          done = false;
        }           
      }
    });
  }
  return done; // here, It always returns 'undefined'.
};

使用延遲對象來利用角度承諾。 如果defered.resolve() ,它將調用.then

var answerArr = $scope.homework.items;
var len = answerArr.length;
$scope.$on('appChange', function(e, doc) {
  hwService.readyToSubmit(answerArr, len).then(function(done){
    $scope.done = done;
  });
});

關鍵是您不能返回done變量,因為當您想返回它時,您的for循環中的回調函數:

appStore.getDoc(id).then(function(doc) {
    //...
})

還未接到電話。 因為正如您在問題中也提到的那樣,它是一個asynchronous function

您有2個選項,首先是使用Angular Promise,這在另一個答案中有描述,但是您還有另一個解決方案,其在readyToSubmit函數中使用回調:

var done = false;
var readyToSubmit = function(answerArr, len, callback) {
  var threshold = 0;
  for (var i = 0; i < answerArr.length; i++) {
    var id = answerArr[i].focus + '_' + userData.uid;
    appStore.getDoc(id).then(function(doc) {
      if (doc.doneRate == 100) {
        threshold++;
        if (threshold == len) {
          callback(true);
        } else {
          callback(false);
        }
      }
    });
  }
  //no need to return anything
  //return done;
};

然后在您的角度范圍內使用:

var answerArr = $scope.homework.items;
var len = answerArr.length;
$scope.$on('appChange', function(e, doc) {
  hwService.readyToSubmit(answerArr, len, function(done){
      $scope.done = done;
  });
});

這樣,您必須要考慮的是這一行代碼:

$scope.done = done;

將不止一次地被致電。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM