异步 JS - 瀑布中的函数未正确执行回调
Async JS - function in waterfall not executing callback properly
我正在尝试从函数 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 没有执行(它实际上正在执行——但你在尝试从 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);
});
这里是 "flow of 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);
});
我正在尝试从函数 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 没有执行(它实际上正在执行——但你在尝试从 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);
});
这里是 "flow of 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);
});