简体   繁体   English

如何正确使用defer()?

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

How do I use defer correctly? 如何正确使用延期? I've got two functions here, in which one defer is used correctly? 我这里有两个函数,其中一个延迟正确使用了吗? In which one it is used incorrectly? 在哪一个中使用不正确? And why resp. 以及为什么要回答。 why not? 为什么不?

First example: 第一个例子:

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;
},

Second example: 第二个例子:

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);
  });
},

The oneFunction does nothing asynchronously. oneFunction异步不执行任何操作。

The anotherFunction does something asynchronously (retrieving data from an external database). anotherFunction异步执行某些操作(从外部数据库检索数据)。

EDIT: Thanks to @Bergi the correct function should look like this: 编辑:感谢@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);
  });
},

You've used $q.defer correctly in the second example [1] - creating a promise for the response of the db.allDocs asynchronous call (and nothing else). 在第二个示例[1]中,您已正确使用$q.defer -为db.allDocs异步调用的响应创建一个承诺(仅此而已)。 Altough pochdb seems to already return promises, as @Benjamin mentions in the comments, so it's unnecessary (but not wrong). 正如@Benjamin在评论中提到的那样,完全pochdb似乎已经返回了promise,所以这是不必要的(但不是错误的)。

The first example is just a mess, convoluting the construction of the promise with the error logging and that ominous loop. 第一个例子只是一团糟,用错误日志记录和那个不祥的循环来混淆promise的构造。

1: Except for dfd.promise() , which is not a function but a property. 1: dfd.promise()除外,它不是函数而是属性。 Go for dfd.promise.then(…) . 进入dfd.promise.then(…)


However, that loop is a very different topic, and seems to be wrong in both snippets. 但是,该循环是一个非常不同的主题,在两个片段中似乎都是错误的。 Some points: 一些要点:

  • In the second snippet, your return from the callback function in the body of the loop, right on the first iteration that fulfills the predicate. 在第二个代码段中,您将从循环主体中的回调函数return ,恰好在满足谓词的第一个迭代中。
  • If oneFunction(qc) is not asynchronous, it doesn't need to (read: shouldn't) return a promise - or if it does not, that .then(…) call is wrong. 如果oneFunction(qc)不是异步的,则不需要(读:不应)返回诺言-否则,则.then(…)调用是错误的。
  • anotherFunction(qc) seems to return a promise (it's asynchronous as you say). anotherFunction(qc)似乎返回一个承诺(正如您所说的那样是异步的)。 But you must not pass that promise to .then() , a callback function is expected there! 但是您一定不能将那个承诺传递给.then() ,那里应该有一个回调函数!
  • Same thing for foo.push(qc) - it's not a callback function that you would pass to .then() . 对于同样的事情foo.push(qc) -这不是一个回调函数,你会传递给.then()
  • After all, you are doing something asynchronous in that loop . 毕竟,您正在该循环中执行异步操作。 Here, you have to use Promise.all now! 在这里, 您必须立即使用 Promise.all

If I had to bet, I'd say you need 如果我必须打赌,我会说你需要

.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