Nodejs中异步函数的返回值
Posted
技术标签:
【中文标题】Nodejs中异步函数的返回值【英文标题】:return value from asynchronous function in Nodejs 【发布时间】:2013-09-27 20:40:26 【问题描述】:我正在使用 nodejs 通过 Mongoose 从 Mongodb 查询数据。 获取数据后,我想在响应客户端之前对该数据做一些事情。但我无法获得返回值。在 Google 上查看后,我了解到 Node.js 函数是异步 javascript 函数(非 I/O 阻塞)。我试试这个 tut (http://www.youtube.com/watch?v=xDW9bK-9pNY) 但它不起作用。下面是我的代码。 myObject 在“find()”函数内部被赋值,在“find()”函数外部未定义。那么我应该怎么做才能获取数据呢?谢谢!
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');
【问题讨论】:
这是我来自 github 的帖子:github.com/LearnBoost/mongoose/issues/… 【参考方案1】:您获得未定义值的原因是 find 函数是异步的,并且可以随时完成。在您的情况下,它是在您使用 console.log()
之后完成的,因此在您访问它们时这些值是未定义的。
要解决此问题,您只能使用 find 函数回调中的值。它看起来像这样:
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
);
);
数据处理已移至等待上一次迭代完成的循环。这样,我们可以确定最后一个回调何时触发,以便在包装函数中触发回调。
【讨论】:
感谢hexacyanide,但它不起作用,它无法读取docs[i]._id的属性【参考方案2】:请记住,执行 console.log 函数时,查询尚未完成,因此将显示“未定义”。这就是nodeJS异步性的本质。
例如,
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); // <-- Initially, this value will be undefined. After some miliseconds (Or the duration of the .exec function, myObject will contain the results.
如果您真的想等到查询完成后再使用这些值,我建议您将 app.listen(3000);
和 console.log('Listening on port 3000');
移到函数的最终回调中。
我还建议您查看this 节点模块。它将帮助您更轻松地构建异步/同步函数,并允许您在所有异步函数完成时执行回调。
【讨论】:
我在收件箱中看到“如果您只想在全局范围内设置/获取值(Ej. 在 Person.find().exec()... 之外)”,但我可以在这里看到它,它在哪里?以上是关于Nodejs中异步函数的返回值的主要内容,如果未能解决你的问题,请参考以下文章
node js - 当函数依赖于内部的异步函数时,如何从函数返回值
从 Nodejs 中的 mySQL 获取数据时如何从 Async/await 函数获取返回值
Kotlin 协程Flow 异步流 ① ( 以异步返回返回多个返回值 | 同步调用返回多个值的弊端 | 尝试在 sequence 中调用挂起函数返回多个返回值 | 协程中调用挂起函数返回集合 )
Kotlin 协程Flow 异步流 ① ( 以异步返回返回多个返回值 | 同步调用返回多个值的弊端 | 尝试在 sequence 中调用挂起函数返回多个返回值 | 协程中调用挂起函数返回集合 )