Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 将数据异步推送到节点中的阵列_Node.js_Mongodb_Asynchronous - Fatal编程技术网

Node.js 将数据异步推送到节点中的阵列

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 = [];

我在另一个mongoose查询中调用mongoose查询。当我将结果推送到数组时,当我最后检查它时,它是空的。经过仔细研究,发现问题在于这是异步执行的。但是找不到解决问题的方法。我的代码如下

    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

你能给我举个例子,说明如何用回调来做这件事吗!如果可以,那将是一个很大的帮助!你能给我举个例子,说明如何用回调来做这件事吗!如果可以,那将是一个很大的帮助!