Nodejs 请教mongoose查询中回调函数怎样能拿到查询参数的值?
Nodejs 请教mongoose查询中回调函数怎样能拿到查询参数的值?
我需要在一个for循环中进行数据库查询,如果没有匹配把对应的index存进一个数组。
for ( var index = 0; index < 100; index++) {
mongooseModel.findOne({ id: index }, function (err, model) {
if (!model) {
array.push(index);
}
});
}
由于mongoose的回调函数是异步的,我这么写存的index值是有问题的。有什么办法能把查询参数传给回调函数呢?
当然可以!你遇到的问题是因为 findOne
方法是异步的,而你的 for
循环会立即执行完毕,导致所有的回调函数在执行时都使用了最后一次的 index
值。
为了解决这个问题,你可以使用闭包或者箭头函数来捕获每次循环中的 index
值。下面是两种方法的具体实现:
方法一:使用闭包
for (var index = 0; index < 100; index++) {
(function(index) { // 立即执行函数表达式创建闭包
mongooseModel.findOne({ id: index }, function (err, model) {
if (!model) {
array.push(index);
}
});
})(index); // 传递当前的 index 值
}
方法二:使用箭头函数(ES6)
for (let index = 0; index < 100; index++) { // 使用 let 关键字
mongooseModel.findOne({ id: index }, (err, model) => {
if (!model) {
array.push(index);
}
});
}
解释
-
闭包:通过创建一个立即执行函数表达式(IIFE),将当前的
index
值作为参数传递进去。这样每次循环都会创建一个新的作用域,从而保留当前的index
值。 -
箭头函数:使用
let
替换var
可以让index
在每次迭代时都有一个新的绑定。箭头函数会继承外部作用域的index
值,而不是每次都引用循环变量的最后值。
这两种方法都可以确保每次回调函数都能正确地获取到当前的 index
值。希望这对你有所帮助!
试一下async模块:https://github.com/caolan/async
<pre><code> var list = [0…100]; async.map(list, function (callback) { mongooseModel.findOne({ id: index }, callback); }, function (err, results) { //results.filter(function (item) {return item;});//如果有需要过滤空值的话,当然也可以用async.filter //results就是你想要的 }); </pre></code>
在使用 Mongoose 进行查询时,由于回调函数是异步执行的,直接在循环中使用 index
变量会导致所有回调函数都拿到循环结束后的最终 index
值。为了解决这个问题,可以在循环中使用闭包来捕获每次迭代中的 index
值。
下面是具体的示例代码:
for (var index = 0; index < 100; index++) {
// 使用闭包捕获当前的index值
(function(currentIndex) {
mongooseModel.findOne({ id: currentIndex }, function(err, model) {
if (!model) {
array.push(currentIndex);
}
});
})(index); // 立即调用函数表达式,并传入当前的index值
}
在这个示例中,我们创建了一个立即执行的函数表达式(IIFE),它接受 currentIndex
作为参数,并将该参数传给回调函数。这样,在每次迭代中,currentIndex
都会捕获当前的 index
值,从而确保每个回调函数都能拿到正确的 index
值。
另外,如果你使用的是较新的 JavaScript 版本,可以使用 let
来声明 index
,因为 let
具有块级作用域,可以避免变量提升的问题。
for (let index = 0; index < 100; index++) {
mongooseModel.findOne({ id: index }, function(err, model) {
if (!model) {
array.push(index);
}
});
}
这样,在每次迭代中,index
的值都会被正确捕获,而不会被后续迭代覆盖。