簡體   English   中英

如何正確使用defer()?

[英]How to use defer() the right way?

如何正確使用延期? 我這里有兩個函數,其中一個延遲正確使用了嗎? 在哪一個中使用不正確? 以及為什么要回答。 為什么不?

第一個例子:

getFoo1: function() {
  var dfd = $q.defer();

  db.allDocs({include_docs: true}, function(err, response) {
    if(err) {
      console.log(err);
      dfd.reject(err);
    } else {
      var qcs = [];
      for(var i=0; i < response.total_rows; i++) {
        if(response.rows[i].doc.type == 'bar') {

          var qc = {id: response.rows[i].doc._id,
            isFoo: true
          };

          oneFunction(qc)
          .then(anotherFunction(qc))
          .then(qcs.push(qc));
        }
      }
      dfd.resolve(qcs);
    }
  });
  return dfd.promise;
},

第二個例子:

getFoo2: function() {
  var dfd = $q.defer();

  db.allDocs({include_docs: true}, function(err, response) {
    if(err) {
      dfd.reject(err);
    } else {
      dfd.resolve(response);
    }
  });

  return dfd.promise
  .then(function(response) {
    var foo = [];
    for(var i=0; i < response.total_rows; i++) {
      if(response.rows[i].doc.type == 'bar') {
        var qc = {id: response.rows[i].doc._id,
          isFoo: true
        };

        return oneFunction(qc)
        .then(anotherFunction(qc))
        .then(foo.push(qc));
      }   
    }
  }, function(err){
     console.log(err);
  });
},

oneFunction異步不執行任何操作。

anotherFunction異步執行某些操作(從外部數據庫檢索數據)。

編輯:感謝@Bergi,正確的功能應如下所示:

getFoo3: function() {
  var dfd = $q.defer();

  db.allDocs({include_docs: true}, function(err, response) {
    if(err) {
      dfd.reject(err);
    } else {
      dfd.resolve(response);
    }
  });

  return dfd.promise
  .then(function(response) {
    var foos = [];

  for (var i=0; i < response.total_rows; i++) {
    if (response.rows[i].doc.type == 'bar') {
      var qc = {id: response.rows[i].doc._id,
        isFoo: true
      };
      var foo = oneFunction(qc);
      foos.push(foo);
    }
  }

  var promises = foos.map(anotherFunction); // make a promise for each foo
  return $q.all(promises);

  }, function(err){
     console.log(err);
  });
},

在第二個示例[1]中,您已正確使用$q.defer -為db.allDocs異步調用的響應創建一個承諾(僅此而已)。 正如@Benjamin在評論中提到的那樣,完全pochdb似乎已經返回了promise,所以這是不必要的(但不是錯誤的)。

第一個例子只是一團糟,用錯誤日志記錄和那個不祥的循環來混淆promise的構造。

1: dfd.promise()除外,它不是函數而是屬性。 進入dfd.promise.then(…)


但是,該循環是一個非常不同的主題,在兩個片段中似乎都是錯誤的。 一些要點:

  • 在第二個代碼段中,您將從循環主體中的回調函數return ,恰好在滿足謂詞的第一個迭代中。
  • 如果oneFunction(qc)不是異步的,則不需要(讀:不應)返回諾言-否則,則.then(…)調用是錯誤的。
  • anotherFunction(qc)似乎返回一個承諾(正如您所說的那樣是異步的)。 但是您一定不能將那個承諾傳遞給.then() ,那里應該有一個回調函數!
  • 對於同樣的事情foo.push(qc) -這不是一個回調函數,你會傳遞給.then()
  • 畢竟,您正在該循環中執行異步操作。 在這里, 您必須立即使用 Promise.all

如果我必須打賭,我會說你需要

.then(function(response) {
  var foos = [];
  for (var i=0; i < response.total_rows; i++) {
    if (response.rows[i].doc.type == 'bar') {
      var qc = {id: response.rows[i].doc._id,
        isFoo: true
      };
      var foo = oneFunction(qc);
      foos.push(foo);
    }
  }
  var promises = foos.map(anotherFunction); // make a promise for each foo
  return $q.all(promises);
})

暫無
暫無

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

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