从函数范围内获取数组数据

时间:2019-03-04 17:08:35

标签: javascript node.js express

我目前正在尝试使用在函数作用域内填充的数组。我的主要问题是,每当我尝试将数组作为信息发送时,系统就会告诉我它为空。

Hare是我的嵌套函数:

exports.getUserDetails = async function(req ,res ,next){
  try{
      Stats.find({map:"France"}).sort({lapTime:1}).limit(3).then(response =>{
          var resultArray=[]; // <----Here is where I've innitialised my array
          for(var item = 0; item < response.length; item++){
                const singleDriverId = response[item].driver;
                const playedMap = response[item].map; // single Map etry from the stats Object
                const timedLap = response[item].lapTime; //single lapTime entry from the stats Object

                User.find({"_id" : singleDriverId}, function(err, result){
                  if (err) throw err;
                  for (var i = 0; i< result.length; i++){

                   //setting up the Object to populate the Array.
                    var finalResult = {
                        "driver": result[i].firstName + " " + result[i].lastName,
                        "map": playedMap,
                        "laptime": timedLap
                      }
                      //<------populating the Array
                      resultArray.push(finalResult);
                    }
                  });
            }
            console.log(resultArray) // prints an empty Array []
            res.status(200).json({status: 200, data: resultArray, message: "Successfully got the user details."});
        })   
    }catch(error){
        console.log(error);
        res.status(400);
    }
}

我认为以某种方式resultArray.push(finalResult);“空”可以打印出来吗?

有人对为什么发生这种情况有什么建议,我该如何解决?

  

我正在尝试从resultArray.push(finalResult)

接收单个数组

2 个答案:

答案 0 :(得分:1)

问题的通用示例(javascript的异步特性)

function getData(cb) {
  setTimeout(() => cb(Date.now()), Math.random() * 1000);
}


const result = [];
for (var i = 0; i < 10; i++) {
  getData((data) => {
    result.push(data);
  });
}

console.log(result); // empty :O

通用解决方案(完成后运行done

function getData(cb) {
  setTimeout(() => cb(Date.now()), Math.random() * 1000);
}


const result = [];
const count = 10;
for (var i = 0; i < count; i++) {
  getData((data) => {
    result.push(data);
    done();
  });
}

var called = 0;
function done() {
  called++;
  if (called === count) {
    console.log(result);  // desired result \O/
  }

}

当然,现在有了promise和async / await,一切都变得更加简单(使用async / await,它看起来几乎就像是一个同步代码)。有多篇文章以及如何使用它们的提示。

对于您的代码,它应该是这样的(请注意,当您进行网络请求时,响应的顺序可能与发送请求的顺序不同,因此resultArray中的项目可能与来自响应):

exports.getUserDetails = async function(req ,res ,next){
  try{
      Stats.find({map:"France"}).sort({lapTime:1}).limit(3).then(response =>{
          var resultArray=[]; // <----Here is where I've innitialised my array
          for(var item = 0; item < response.length; item++){
                const singleDriverId = response[item].driver;
                const playedMap = response[item].map; // single Map etry from the stats Object
                const timedLap = response[item].lapTime; //single lapTime entry from the stats Object

                User.find({"_id" : singleDriverId}, function(err, result){
                  if (err) throw err;
                  for (var i = 0; i< result.length; i++){

                   //setting up the Object to populate the Array.
                    var finalResult = {
                        "driver": result[i].firstName + " " + result[i].lastName,
                        "map": playedMap,
                        "laptime": timedLap
                      }
                      //<------populating the Array
                      resultArray.push(finalResult);
                      done(); // function is run whenever data is pushed
                    }
                  });
            }
            var count = 0;
            function done() {
              count++;
              if (count === response.length) { // this code block is run only when all items are pushed into the resultArray
                console.log(resultArray) 
              }
            }
            res.status(200).json({status: 200, data: resultArray, message: "Successfully got the user details."});
        })   
    }catch(error){
        console.log(error);
        res.status(400);
    }
}

可能User.find也支持promise,因此使用Promise.all的更简单和可读性更好。

答案 1 :(得分:-1)

仅使用if语句,它将起作用

if(resultArray){             console.log(resultArray)//打印一个空数组[]             res.status(200).json({状态:200,数据:resultArray,消息:“已成功获取用户详细信息。”}); }