问题
I'm using the async module's forEachOf method to print the end result after iterating through an object. Here is a shortened version of what I'm doing:
var async = require('async'),
cheerio = require('cheerio'),
request = require('request');
var returnArray = [];
async.forEachOf(myObj, function (value, key, callback) {
var anotherObj = {};
anotherObj.type = "val1";
request(someurl, function(err, res, body) {
if (err) {
return callback(err);
}
var $ = cheerio.load(body);
anotherObj.name = "val2";
var miniObj = {};
$('#some-element', "#an-id").each(function(i, value) {
var val = value.value;
miniObj[size] = val;
});
anotherObj.miniObj = miniObj;
returnArray.push(anotherObj);
return callback();
});
}, function (err) {
if (err) {
console.error(err.message);
}
console.log(returnArray);
});
However, when I run the program, nothing (namely, 'returnArray') gets printed to the console like it should be.
For reference, I have looked at these other, similar posts:
- Using async module to fire a callback once all files are read (seems outdated, is using the wrong method, and doesn't address the issue)
- Last callback not being called using async (doesn't address the issue)
I'm not sure what I'm doing wrong here. Could anyone please point out what I'm doing wrong?
Thanks!
EDIT: So I think I finally figured out what I was doing wrong. In a different example I provided earlier HERE, using Runnable I forgot to add a 'return callback()' statement. Then it worked. The only difference between that and this example being that my 'return callback()' statement in the above-provided example is itself called within another asynchronous method. I think in order to fix my problem I will somehow have to make sure (probably using some control flow function in async's library) to call 'return callback()' at the correct 'scope/level' after the second asynchronous method has finished. I think I will attribute this, my mistake, to the lack of documentation on proper usage of the 'return callback()' statement in the async docs. I will update this post with a solution once I figure it out (and catch up on some sleep)!
回答1:
Your statement:
if (err) {
return callback(err);
}
is not valid for asynchronous programming. Instead, you should do:
if(err) callback(err);
This is why you aren't getting anything returned. I rewrote your code with async concepts applied:
var async = require('async'),
var cheerio = require('cheerio'),
var request = require('request');
var returnArray = [];
async.forEachOf(myObj, function (value, key, next) {
var anotherObj = {};
anotherObj.type = "val1";
request(someurl, function(err, res, body) {
if (err) next(err);
var $ = cheerio.load(body);
anotherObj.name = "val2";
var miniObj = {};
async.each($('#some-element', "#an-id"), function (value, next) {
var val = value.value;
miniObj[size] = val;
});
anotherObj.miniObj = miniObj;
returnArray.push(anotherObj);
next();
});
}, function (err) {
if (err) console.error(err.message);
console.log(returnArray);
callback(returnArray);
});
Notice that you have two different named callbacks. The outer function callback is called callback
. The inner function callback is called next
.
来源:https://stackoverflow.com/questions/31097142/optional-callback-not-being-called-in-the-node-js-async-modules-foreachof-metho