繁体   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