确保任务按顺序完成

时间:2017-05-30 12:09:42

标签: javascript node.js asynchronous

我们正在使用mailgun,我们的一些用户被放置在抑制列表中。一次删除多个用户可能会很繁琐,所以我想通过API做同样的事情。我还想保存一些有关用户电子邮件被退回的原因的信息,以便我可以将其转发给他们。我这样做是这样的:

fs.readFile('emails.txt', 'utf8', function(err, data) { 
  if (err) throw err;
  var emails = data.split(',');
  async.eachSeries(emails, function(email, cb){
    options.url = 'https://api.mailgun.net/v3/XXXXX.com/bounces/'+email

    request.get(options, function(err, res, body){
      body = JSON.parse(body);
      error_code = body.error;
      bounced_at = body.created_at;

      var str = "\n Error code: "+body.error+" for email: "+email+" was bounced at: "+body.created_at
      fs.appendFile("output.txt", str, function(err){
        if(err) console.log(err)
        console.log("Details were saved to output.txt")
      })
    });
    request.del(options, function(err, res, body){
      if(err){
        cb(err);
      } else {
        console.log('Email: '+email+' has been unsuppressed');
      }
    })
    cb(null);
  }, function(err){
    if(err){
      console.log(err);
    } else {
      console.log('All bounced emails removed')
    }
  });
});

以下是5位用户的测试。

输入:

test1@ah.com,test2@ah.com,test3@ah.com,test4@ah.com,test5@ah.com

输出:

Error code: 4.4.4 for email: test4@ah.com was bounced at: Tue, 30 May 2017 11:40:17 UTC Error code: 3.3.3 for email: test3@ah.com was bounced at: Tue, 30 May 2017 11:40:05 UTC Error code: 2.2.2 for email: test2@ah.com was bounced at: Tue, 30 May 2017 11:39:57 UTC Error code: 1.1.1 for email: test1@ah.com was bounced at: Tue, 30 May 2017 11:39:45 UTC Error code: 5.5.5 for email: test5@ah.com was bounced at: Tue, 30 May 2017 11:40:27 UTC

我们可以看到这些没有按顺序完成,这很好。当然,在async docs here中就足够了。

  

注意,由于此函数并行地将iteratee应用于每个项目,因此无法保证iteratee函数将按顺序完成。

然而,当我用十封电子邮件进行测试时:

test1@ah.com,test2@ah.com,test3@ah.com,test4@ah.com,test5@ah.com,test6@ah.com,test7@ah.com,test7@ah.com,test8@ah.com,test9@ah.com,test10@ah.com

这是输出:

Error code: 2.2.2 for email: test2@ah.com was bounced at: Tue, 30 May 2017 11:43:57 UTC Error code: undefined for email: test10@ah.com was bounced at: undefined Error code: 1.1.1 for email: test1@ah.com was bounced at: Tue, 30 May 2017 11:43:50 UTC Error code: 8.8.8 for email: test8@ah.com was bounced at: Tue, 30 May 2017 11:44:43 UTC Error code: 3.3.3 for email: test3@ah.com was bounced at: Tue, 30 May 2017 11:44:05 UTC Error code: 6.6.6 for email: test6@ah.com was bounced at: Tue, 30 May 2017 11:44:28 UTC Error code: 5.5.5 for email: test5@ah.com was bounced at: Tue, 30 May 2017 11:44:21 UTC Error code: 4.4.4 for email: test4@ah.com was bounced at: Tue, 30 May 2017 11:44:13 UTC Error code: undefined for email: test7@ah.com was bounced at: undefined Error code: 9.9.9 for email: test9@ah.com was bounced at: Tue, 30 May 2017 11:44:55 UTC

好像在某些情况下,我的request.get()是在request.del() - >之后执行的。这导致输出日志在某些地方有Undefined。如何确保始终先执行request.get()

1 个答案:

答案 0 :(得分:0)

使用回调,您可以通过在第一个回调中调用第二个异步函数来指定顺序,其中第一个和第二个是您希望它们执行的顺序。

first("foo", function() {
  // inside callback of first function
  second("bar", function() {
    // second callback. 
    // At this point both functions have terminated in order
...

虽然这对于2或3个嵌套回调是可以的,但你很容易迷失在回调地狱中。

处理异步函数的另一种方法是使用 Promises

当函数返回Promise时,您可以访问.then()方法,该方法将Promise解析时要调用的函数作为参数(第一个异步函数完成异步操作)

看起来像这样:

something_async_way("foo", "bla").then(function() { // do something });

有关Promises here

的更多信息