好吧,您的代码存在许多问题,但其中最主要的一个事实是,您无法将在回调中收到的值保存或操作到该回调之外的任何内容。您的示例已(为清楚起见重写):
var result = []
arry.forEach(function(opt) {
async.call(args, function(err,value) {
result.push(value)
})
})
// result is empty here!
无法按预期工作,因为您无法知道内部回调何时完成。
根据定义,回调会在未来的某个时间触发,由于你不知道什么时候,你必须使用传递给回调的结果进行所有计算 在回调本身!
否则会产生不一致的结果。
更新 - 重新评论
(注意:在火车上匆忙在 iPad 上打字,如果需要,稍后会修复。)
最好的方法是使用 Promises 来聚合结果。这是一个天真的例子:
/*
* given a value and an optional array (accum),
* pass the value to the async func and add its result to accum
* if accum is not an array, make it one
* return accum
*/
var do_something = (value, accum) => {
// on first pass, accum will be undefined, so make it an array
accum = Array.isArray(accum) ? accum : []
return new Promise((resolve, reject) => {
async_func(value, (err, res) => {
if(err) {
reject(err)
}
accum.append(res)
resolve(accum)
})
})
}
/*
* for each member of input array, apply do_something
* then operate on accumulated result.
*/
Promise.map(input, do_something)
.then(results => {
// results will contain the accumulated results from all
// the mapped operations
})
.catch(err => {
throw err
})
更新 - 每条评论
仅使用回调,您可以使用以下方法获得相同的结果:
const inputs = [...] // array of inputs to pass to async function
const expected_num_of_results = inputs.length
let results = []
const onComplete = (results) => {
// do something with completed results here
console.log(`results: ${results}`);
}
const onResult = (err, res) => { // callback to async_func
if(err) {
throw new Error(`on iteration ${results.length+1}: ${err}`)
}
results.push(res) // save result to accumulator
if( results.length >= expected_num_of_results) { // are we done?
onComplete(results) // process results
}
}
// example async func - REPLACE with actual async function
const async_func = (val,cb) => {
// call callback with no error and supplied value multiplied by 2
cb(null,val*2)
}
// wrapper that takes one value
// and calls async_func with it and predefined callback
const do_async = (value) => {
async_func(value, onResult)
}
// process inputs
inputs.forEach(do_async)
所以:
const inputs = [1,2,3,4,5]
将打印:
results: 2,4,6,8,10