【问题标题】:Async JS - function in waterfall not executing callback properly异步 JS - 瀑布中的函数未正确执行回调
【发布时间】:2018-03-25 08:00:42
【问题描述】:

我试图从函数 getFeed()、feedItems 和 feedMeta 中恢复值。我收到以下信息:

/Users/react-backend/node_modules/async/dist/async.js:228
    return supportsSymbol && fn[Symbol.toStringTag] === 'AsyncFunction';
                               ^

TypeError: Cannot read property 'Symbol(Symbol.toStringTag)' of undefined
    at isAsync (/Users/react-backend/node_modules/async/dist/async.js:228:32)
    at wrapAsync (/Users/react-backend/node_modules/async/dist/async.js:232:12)
    at /Users/react-backend/node_modules/async/dist/async.js:3866:9
    at replenish (/Users/react-backend/node_modules/async/dist/async.js:998:17)
    at /Users/react-backend/node_modules/async/dist/async.js:1002:9
    at eachOfLimit (/Users/react-backend/node_modules/async/dist/async.js:1027:24)
    at /Users/react-backend/node_modules/async/dist/async.js:1032:16
    at _parallel (/Users/react-backend/node_modules/async/dist/async.js:3865:5)
    at Object.series (/Users/react-backend/node_modules/async/dist/async.js:4721:5)
    at Object.<anonymous> (/Users/react-backend/feedParser2.js:114:7)
    at Module._compile (module.js:662:30)
    at Object.Module._extensions..js (module.js:673:10)
    at Module.load (module.js:575:32)
    at tryModuleLoad (module.js:515:12)
    at Function.Module._load (module.js:507:3)
    at Function.Module.runMain (module.js:703:10)

使用下面的代码时在控制台中:

function getFeed(callback) {
    let req = request(urlTestFeed);
    let feedparser = new FeedParser(feedParserOptions);
    let feedItems = [];
    let feedMeta = null;

    req.on('response', function(response) {
        let stream = this;
        if (response.statusCode == 200) {
            stream.pipe(feedparser);
        }
    });

    req.on('error', function(err) {
        console.log('getFeed: err.message == ' + err.message);
    });

    feedparser.on('meta', function() {
        try {
            feedMeta = this.meta;
        } catch (err) {
            console.log('getFeed: err.message == ' + err.message);
        }
    });

    feedparser.on('readable', function() {
        try {
            let item = this.read();
            if (item !== null) {
                feedItems.push(item);
            }
        } catch (err) {
            console.log('getFeed: err.message == ' + err.message);
        }
    });

    feedparser.on('end', function() {
        callback(undefined, feedItems, feedMeta);
    });

    feedparser.on('error', function(err) {
        console.log('getFeed: err.message == ' + err.message);
        callback(err);
    });
}

异步:

async.waterfall([
        getFeed(function(err, feedItems, feedMeta) {
            console.log(feedMeta)
            if (!err) {
                if (feedMeta.title && feedMeta.description && feedMeta.link) {

                }
            }
        })]);

如果我将 callback(undefined, feedItems, feedMeta); 添加到 getFeed 的最后一行:

function getFeed(callback) {
    let req = request(urlTestFeed);
    let feedparser = new FeedParser(feedParserOptions);
    let feedItems = [];
    let feedMeta = null;

    req.on('response', function(response) {
        let stream = this;
        if (response.statusCode == 200) {
            stream.pipe(feedparser);
        }
    });

    req.on('error', function(err) {
        console.log('getFeed: err.message == ' + err.message);
    });

    feedparser.on('meta', function() {
        try {
            feedMeta = this.meta;
        } catch (err) {
            console.log('getFeed: err.message == ' + err.message);
        }
    });

    feedparser.on('readable', function() {
        try {
            let item = this.read();
            if (item !== null) {
                feedItems.push(item);
            }
        } catch (err) {
            console.log('getFeed: err.message == ' + err.message);
        }
    });

    feedparser.on('end', function() {
        callback(undefined, feedItems, feedMeta);
    });

    feedparser.on('error', function(err) {
        console.log('getFeed: err.message == ' + err.message);
        callback(err);
    });
    callback(undefined, feedItems, feedMeta);
}

我在控制台中得到以下信息:

null
/Users/react-backend/feedParser2.js:119
            if (feedMeta.title && feedMeta.description && feedMeta.link) {
                         ^
TypeError: Cannot read property 'title' of null

当我添加回调时,feedMeta 的值发生了什么变化?如何将 feedparser、feeditems 和 err 中的值传递给 Async.waterfall?

【问题讨论】:

  • 我认为 getFeed 没有执行。
  • getFeed 没有执行,因为我在异步调用中发送了参数。请删除这篇文章,模组。

标签: javascript asynchronous async.js


【解决方案1】:

猜测这太少,太晚了 - 但问题不在于 getFeed 没有执行(它实际上正在执行 - 但您在尝试从 URL 读取结果返回之前返回)。问题是您将异步模式与同步模式混合在一起。

我建议在将其移入异步瀑布之前简化您尝试做的事情。

具体来说,将您的 readFeed 内容改为:

function getFeed(callback){
    console.log('getFeed');
    return callback(null, [], {});
}

然后使用以下方式调用它

async.waterfall([
    function first (next){
        getFeed(function(err, feedItems, feedMeta) {
            console.log('getFeed cb:', feedMeta);
            if (!err) {
                if (feedMeta.title && feedMeta.description && feedMeta.link) {

                }
            }
            return next(err);
        })        
    }
],
function(err){
    console.log('waterfall done: err:',err);
});

以下是“瀑布流”的示例(即,瀑布被赋予了多个功能):

async.waterfall([
    function first (next){
        getFeed(function(err, feedItems, feedMeta) {
            console.log('getFeed cb:', feedMeta);
            if (!err) {
                if (feedMeta.title && feedMeta.description && feedMeta.link) {

                }
            }
            return next(null, "rando");        
        })
    },
    function second(input, next){
        console.log('second: input:', input);
        return next('something bad happened');
    }
],
function(err){
    console.log('waterfall done: err:',err);
});

【讨论】:

  • 谢谢。事实上,我还在努力。 next 是传递给瀑布中下一个函数的数据的名称吗?
  • "next" 可以命名为任何名称 - 它只是用于推进瀑布的回调。一旦您的系列(瀑布函数数组)完成 - 调用最终回调(“瀑布完成”日志所在的位置)。从技术上讲,如果您的瀑布中有多个函数 - 每个瀑布函数的返回都会馈送到每个后续函数。注释对于代码来说不是很好 - 可以显示在另一个答案中。
  • 我现在知道了。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-26
  • 2023-03-15
  • 1970-01-01
  • 2017-08-03
  • 2014-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多