简体   繁体   English

异步JS-Waterfall中的函数无法正确执行回调

[英]Async JS - function in waterfall not executing callback properly

I am trying to get back to values from the function getFeed(), feedItems and feedMeta. 我试图从函数getFeed(),feedItems和feedMeta返回值。 I receive the following: 我收到以下信息:

/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)

in the console when using the code immediately below: 在控制台中使用下面的代码时:

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: 异步:

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

                }
            }
        })]);

If I add callback(undefined, feedItems, feedMeta); 如果我添加callback(undefined, feedItems, feedMeta); to the last line in getFeed: 到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);
}

I get the following in the console: 我在控制台中得到以下内容:

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

What happened to the value of feedMeta when I added the callback? 添加回调后,feedMeta的值发生了什么? How can I pass the values from feedparser,feeditems, and, err to Async.waterfall? 如何将值从feedparser,feeditems和err传递给Async.waterfall?

Guessing this is too little, too late - but the problem isn't that getFeed isn't executing (it is actually executing - but you're returning before you get the results back from trying to read from a URL). 猜测这太少了,太晚了-但问题不是getFeed没有执行(它实际上正在执行-但是您正在返回,然后尝试从URL读取返回结果)。 The issue is that you're mixing asynchronous patterns with synchronous patterns. 问题是您将异步模式与同步模式混合在一起。

I'd recommend simplifying what you're trying to do before moving this into async waterfall. 我建议您先简化操作,然后再将其移入异步瀑布。

Specifically, gut the contents of your readFeed to be this: 具体来说,将readFeed的内容保留为:

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

Then call it using the following 然后使用以下命令调用它

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

Here is an example of the "flow of waterfall" (ie more than a single function being given to the waterfall): 这是“瀑布流”的示例(即,给瀑布提供了多个功能):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM