Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
159 views
in Technique[技术] by (71.8m points)

javascript - return value from asynchronous function in Nodejs

I am using nodejs to query data from Mongodb throught Mongoose. After get the data, I want do something on that data before responding it to client. But I can not get the return-value. After looking on Google, I have learned Node.js functions is asynchronous javascript function (non I/O blocking). I try this tut (http://www.youtube.com/watch?v=xDW9bK-9pNY) but it is not work. Below is my code. The myObject is valued inside "find()" function and undefined outside "find()" function. So what should I do to get the data? Thanks!

var Person = mongoose.model('Person', PersonSchema);
var Product = mongoose.model('Product', ProductSchema);
var myObject = new Object();

Person.find().exec(function (err, docs) {
    for (var i=0;i<docs.length;i++)
    { 
    Product.find({ user: docs[i]._id},function (err, pers) {
    myObject[i] = pers;
    console.log(myObject[i]); //return the value is ok
    });
    console.log(myObject[i]); //return undefined value
    }
    console.log(myObject); //return undefined value
});
    console.log(myObject); //return undefined value

app.listen(3000);
console.log('Listening on port 3000');
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The reason you're getting undefined values is because the find function is asynchronous, and can finish at any time. In your case, it is finishing after you're using console.log(), so the values are undefined when you're accessing them.

To fix this problem, you can only use the values inside the find function's callback. It would look something like this:

var Person = mongoose.model('Person', PersonSchema);
var Product = mongoose.model('Product', ProductSchema);
var myObject = new Object();

function getData(docs, callback) {
  function loop(i) {
    Product.find({ user: docs[i]._id}, function (err, pers) {
      myObject[i] = pers;

      if (i < docs.length) {
        loop(i + 1);
      } else {
        callback();
      }
    });
  };
  loop(0);
};

Person.find().exec(function(err, docs) {
  getData(docs, function() {
    // myObject has been populated at this point
  });
});

The data processing has been moved to a loop that waits for the previous iteration to complete. This way, we can determine when the last callback has fired in order to fire the callback in the wrapper function.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...