我仍然不能很好地处理异步函数,我有一个项目数组,我试图为每个项目计算一些值并推送到异步函数之外的另一个数组。然后我想做一些统计计算并发送到前端。它的服务器端,nodejs处理程序,我的代码:
exports.register = function (plugin, options, next) {
function isInArray(value, array) {
return array.indexOf(value) > -1;
}
function statistics(values) {
var sum = math.sum(values);
var max = math.max(values);
var min = math.min(values);
var stddev = math.std(values);
var mean = math.mean(values);
var count = values.length;
}
plugin.route({
method: 'GET',
path: '/statistics/{orgId}/layout/{layoutId}',
config: {
pre: [
authorize(hasRole(['OPERATIONAL', 'STRATEGIC', 'LOP', 'TACTICAL']))
],
handler: function (request, reply) {
Category.find()
.where('organization')
.equals(request.params.orgId)
.exec(function (err, categories) {
var weight = [];
var price = [];
var volume = [];
var thisAR = [];
if (err || categories === null) {
return reply(Boom.badRequest('Categoria inexistente'));
} else {
Location.findById(request.params.layoutId)
.exec(function (err, layout) {
if(err) {
console.log(err);
}
var searchItems = function searchItems(category, next) {
Item.find()
.where('category')
.equals(category._id)
.exec(function (err, items) {
if (err) {
console.log(err);
} else {
var valuesToCalculate = [];
var itemsFiltered = [];
_.forEach(items, function(item) {
if(item.location && item.location !== null) {
if(isInArray(item.location.toString(), layout.contents)) {
itemsFiltered.push(item);
}
}
});
valuesToCalculate.push(itemsFiltered.length * category.data.weight);
valuesToCalculate.push(itemsFiltered.length * category.data.price);
valuesToCalculate.push(itemsFiltered.length * category.data.volume);
next(valuesToCalculate);
}
});
}
var onFinish = function onFinish(value, err) {
if(err) {
console.log(err);
}
console.log(value);
thisAR.push.apply(value);
}
async.each(categories, searchItems, onFinish);
console.log(thisAR);
//var arrays = [statistics(weight), statistics(price), statistics(volume)];
//return arrays;
});
}
});
}
}
});
next();
};
答案 0 :(得分:0)
有一些事情对我很突出。首先,如果存在错误或类别为空,则只调用回复。此外,您正在尝试将非null值传递给async.each回调。根据这个:https://github.com/caolan/async#eacharr-iterator-callback,"如果没有发生错误,回调应该在没有参数或显式空参数的情况下运行"。我想你可能会误解onFinish回调如何与async.each一起使用..它不是为每个项调用的,它是在迭代器函数的所有完成时调用的。因此,您应该在searchItems中执行此操作,而不是将项目推送到onFinish中的thisAR。我认为这应该有效:
exports.register = function (plugin, options, next) {
function isInArray(value, array) {
return array.indexOf(value) > -1;
}
function statistics(values) {
var sum = math.sum(values);
var max = math.max(values);
var min = math.min(values);
var stddev = math.std(values);
var mean = math.mean(values);
var count = values.length;
}
plugin.route({
method: 'GET',
path: '/statistics/{orgId}/layout/{layoutId}',
config: {
pre: [
authorize(hasRole(['OPERATIONAL', 'STRATEGIC', 'LOP', 'TACTICAL']))
],
handler: function (request, reply) {
Category.find()
.where('organization')
.equals(request.params.orgId)
.exec(function (err, categories) {
var weight = [];
var price = [];
var volume = [];
var thisAR = [];
if (err || categories === null) {
return reply(Boom.badRequest('Categoria inexistente'));
} else {
Location.findById(request.params.layoutId)
.exec(function (err, layout) {
if(err) {
console.log(err);
}
var searchItems = function searchItems(category, next) {
Item.find()
.where('category')
.equals(category._id)
.exec(function (err, items) {
if (err) {
console.log(err);
} else {
var valuesToCalculate = [];
var itemsFiltered = [];
_.forEach(items, function(item) {
if(item.location && item.location !== null) {
if(isInArray(item.location.toString(), layout.contents)) {
itemsFiltered.push(item);
}
}
});
valuesToCalculate.push(itemsFiltered.length * category.data.weight);
valuesToCalculate.push(itemsFiltered.length * category.data.price);
valuesToCalculate.push(itemsFiltered.length * category.data.volume);
thisAR.push.apply(valuesToCalculate);
}
next(err);
});
}
var onFinish = function onFinish(err) {
if(err) {
console.log(err);
}
console.log(thisAR);
// call reply here
}
async.each(categories, searchItems, onFinish);
console.log(thisAR);
//var arrays = [statistics(weight), statistics(price), statistics(volume)];
//return arrays;
});
}
});
}
}
});
next();
};
答案 1 :(得分:0)
我无法发表评论,因为我是新手,但似乎只删除.apply
中的thisAR.push.apply(valuesToCalculate);
会将完整数组返回到您的console.log。