Node.js 将数据异步推送到节点中的阵列
我在另一个mongoose查询中调用mongoose查询。当我将结果推送到数组时,当我最后检查它时,它是空的。经过仔细研究,发现问题在于这是异步执行的。但是找不到解决问题的方法。我的代码如下Node.js 将数据异步推送到节点中的阵列,node.js,mongodb,asynchronous,Node.js,Mongodb,Asynchronous,我在另一个mongoose查询中调用mongoose查询。当我将结果推送到数组时,当我最后检查它时,它是空的。经过仔细研究,发现问题在于这是异步执行的。但是找不到解决问题的方法。我的代码如下 Bus.find().exec(function(err,buses) { if(err) console.log(err); if (buses[0] != null){ const cords = [];
Bus.find().exec(function(err,buses) {
if(err)
console.log(err);
if (buses[0] != null){
const cords = [];
buses.forEach( function (bus) {
// console.log(bus);
Position.findOne({"busId": bus.busId},{}, {sort : {'time' : -1}}, function (err, position) {
cords.push(position);
console.log(cords);
// console.log(position);
});
console.log(cords);
},
function (err) {
if (err){
console.log(err,"Errrrrrrrrrrrrr");
}
});
console.log(cords);
res.json({cords: cords});
}
好吧,代码中有很多问题,但其中最主要的是,您无法保存回调中接收到的值或对回调之外的任何值执行操作。您的示例已(为清晰起见重写): 它不能像您期望的那样工作,因为您无法知道内部回调何时完成 根据定义,回调将在将来某个时间触发,因为您不知道何时触发,所以必须使用传递给回调本身中回调的结果来执行所有计算强> 否则会导致不一致的结果 更新-重新评论 (注意:在乘坐火车时匆忙在iPad上键入,如果需要,将在以后修复。) 最好的方法是使用承诺来汇总结果。下面是一个天真的例子:
/*
* 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
好吧,代码中有很多问题,但其中最主要的是,您无法保存回调中接收到的值或对回调之外的任何值执行操作。您的示例已(为清晰起见重写): 它不能像您期望的那样工作,因为您无法知道内部回调何时完成 根据定义,回调将在将来某个时间触发,因为您不知道何时触发,所以必须使用传递给回调本身中回调的结果来执行所有计算强> 否则会导致不一致的结果 更新-重新评论 (注意:在乘坐火车时匆忙在iPad上键入,如果需要,将在以后修复。) 最好的方法是使用承诺来汇总结果。下面是一个天真的例子:
/*
* 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
你能给我举个例子,说明如何用回调来做这件事吗!如果可以,那将是一个很大的帮助!你能给我举个例子,说明如何用回调来做这件事吗!如果可以,那将是一个很大的帮助!