node.js async.each 回调,我怎么知道它啥时候完成?

Posted

技术标签:

【中文标题】node.js async.each 回调,我怎么知道它啥时候完成?【英文标题】:node.js async.each callback, how do I know when it's done?node.js async.each 回调,我怎么知道它什么时候完成? 【发布时间】:2013-12-10 22:59:27 【问题描述】:

我正试图围绕 Node.js 和一些异步操作。在下面的代码中,我获取一些 RSS 提要并存储之前没有存储过的文章。该代码有效并存储新文章。但是,我不确定如何更改它,以便我知道何时完成所有文章的解析。例如,每次达到限制时(在 10 篇文章或 5 个提要之后)都会调用每个 async.eachLimit 上的回调。那么我怎么知道它们什么时候完成呢?

var FeedParser = require('feedparser');
var request = require('request');
var mysql = require('mysql');
var async = require('async');

var connection = mysql.createConnection(
        host :  'localhost',
        user : 'someuser',
        password : 'somepass',
        database : 'somedb'
);

connection.connect();

connection.query('SELECT * FROM rssfeed', function(err, rows, fields) 
        if(err == null)
                async.eachLimit(rows, 5, parseFeed, function(err) 
                        if(! err) 
                                //horray
                         else 
                                console.log(err);
                        
                );
        
);

function parseFeed(feed, callback) 
        var articles = [];
        request(feed.link)
        .pipe(new FeedParser())
        .on('error', function(error) 
                callback(error);
        )
        .on('meta', function(meta) 
        )
        .on('readable', function() 
                var stream = this, item;
                item = stream.read();
                if(item != null) 
                        item.rssfeed_id = feed.id;
                        articles.push(item);
                
        )
        .on('finish', function() 
                async.eachLimit(articles, 10, parseArticle, function(err) 
                        if(! err) 
                                console.log('article each callback');
                         else 
                                callback(error);
                        
                );
        );
        callback();

function parseArticle(item, callback) 
        if(item.hasOwnProperty('rssfeed_id') && item.hasOwnProperty('guid') && item.hasOwnProperty('link') && item.hasOwnProperty('title'))
                connection.query('SELECT * FROM rssarticle WHERE rssfeed_id = ? AND guid = ?', [item.rssfeed_id, item.guid], function(err, rows, fields) 
                        if(rows.length == 0)
                                connection.query('INSERT INTO rssarticle SET ?', 
                                        rssfeed_id: item.rssfeed_id,
                                        link: item.link,
                                        title: item.title,
                                        description: item.description,
                                        publish_date: item.pubDate,
                                        guid: item.guid
                                , function(err, result)
                                        if(err != null)
                                                console.log(err);
                                        
                                );
                        
                );
        
        callback();

【问题讨论】:

嗯,在迭代中所有异步操作完成后调用回调,你在寻找其他东西吗? 【参考方案1】:

一方面,您过早地抢先调用您的回调。

function parseFeed(feed, callback) 
  request
    .streamStuff()
    .streamStuff()
    .streamStuff();

  callback();

您不应该在完成之前致电callback。否则,您的“已完成”方法将被调用,但您的异步代码实际上仍在运行。

所以不要这样做:

.on('finish', function() 
    async.eachLimit(articles, 10, parseArticle, function(err) 
        if(! err) 
            console.log('article each callback');
         else 
            callback(error);
        
    );
);
callback();

做事

.on('finish', function() 
    async.eachLimit(articles, 10, parseArticle, function(err) 
        if(! err) 
            // assuming this is a stub and really ends up doing `callback();`
            console.log('article each callback');
         else 
            callback(error);
        
    );
);

【讨论】:

啊哈!我们去吧。我将回调移动到与文章有关的eachLimit。修复了一切。谢谢! 这一切都是为了让事情保持简单,在未来使用更多命名函数(而不是匿名函数),你会更容易看到异步流的方向。 另外,给回调取更合适的名字真的很有用,比如我喜欢用nextdone来区分它们。 +1 - 很好地发现了在异步函数完成之前调用的回调。

以上是关于node.js async.each 回调,我怎么知道它啥时候完成?的主要内容,如果未能解决你的问题,请参考以下文章

Node.js:如何从回调中正确返回对象?

mongoose、express 和 node.js 中回调函数的参数

Node.js 从函数返回一个承诺

async.map 或 async.each 与 async.parallel 有啥区别?

async.map 或 async.each 与 async.parallel 有啥区别?

Node.js - 为啥我的一些回调没有异步执行?