异步并行错误
Async parallel bug?
这里我试图制作一个带有Async.js.参数的函数数组
数组由RunRequest的实例组成,这些实例应该在MakeRequest的循环中设置,就在我尝试将函数数组传递给Async之前。
所以当我把request[i]中的请求传递给RunRequest时,它是好的,但在RunRequest函数内部它是未定义的?
// Process Requests
function RunRequest(db, collection, request, requestHandler, callback) {
console.log('this happening?')
// Connect to the database
db.open(function(err, db) {
if(err) callback(err, null);
// Connect to the collection
db.collection(collection, function(err, collection) {
if (err) callback(err, null);
// Process the correct type of command
requestHandler(db, collection, request, callback);
});
});
}
function MakeRequest(request, requestHandler, collection, callback) {
var data = [];
var doneRequest = function(err, results) {
console.log('done was called')
if (err) callback(err, null);
else if(results) data = data.concat(results);
}
// Make Request Array
var requestArray = [];
for(var i = 0; i < request.length; i++) {
console.log('run request was called')
var dbConnection = new Db('KidzpaceDB', new Server(Host, Port, {auto_reconnect: true}))
requestArray.push(function() {RunRequest(dbConnection, collection, request[i], requestHandler, doneRequest)});
}
// Make all requests in Parallel then invoke callback
Async.parallel(requestArray, function(err, results) {
console.log('Step WORKS')
if(data) {
var uniqueResults = [];
for(var i = 0; i < data.length; i++) {
if( !uniqueResults[data[i]['_id']] ) {
uniqueResults[uniqueResults.length] = data[i];
uniqueResults[data[i]['_id']] = true;
}
callback (null, uniqueResults);
}
}
});
}
// Request Handlers
var FindHandler = function(db, collection, request, callback) {
console.log('FindHandler was called')
console.log('Request Query' + request);
collection.find(request.query, function(err, cursor) {
if (err) callback(err, null);
cursor.toArray(function(err, docs) {
if (err) callback(err, null);
if(docs.length <= 0) console.log("No documents match your query");
var requestResults = [];
for(var i=0; i<docs.length; i++) {
requestResults[requestResults.length] = docs[i];
}
db.close();
callback(null, requestResults);
});
});
}
这只是黑暗中的一枪:
我认为问题在于如何在MakeRequest
内部调用RunRequest
。在第一个for循环中,您正在对request
进行迭代,并在匿名函数中使用request[i]
,但i
在下一次迭代中发生了更改,并且当RunRequest
实际执行时,当前作用域将丢失。
很难复制,但试试这个:
var requestArray = [];
for(var i = 0; i < request.length; i++) {
console.log('run request was called')
var dbConnection = new Db('KidzpaceDB', new Server(Host, Port, {auto_reconnect: true}))
function wrap(dbConnection, collection, request, requestHandler, doneRequest) {
return function() {
RunRequest(dbConnection, collection, request, requestHandler, doneRequest);
}
}
requestArray.push(wrap(dbConnection, collection, request[i], requestHandler, doneRequest));
}
这是一个作用域问题。当循环结束时,变量i
被设置为request.length
,因此request[i]
是undefined
。
用这样的匿名函数包装你的代码:
var requestArray = [];
for(var i = 0; i < request.length; i++) {
(function(i) {
console.log('run request was called');
var dbConnection = ...;
requestArray.push( ... );
})(i);
}
甚至更好(避免创建匿名函数时不必要的开销):
var requestArray = [];
request.forEach( function( el ) {
console.log('run request was called');
// the other code goes here, use el instead of request[i]
});
EDIT不会调用回调,因为您没有正确定义数组中的函数。您将不得不对代码进行一些重构,所以让我向您展示一下它应该如何:
requestArray.push(function(callback) { // <---- note the additional parameter here
// do some stuff, for example call db
db.open(function(err, db) {
if (err) {
callback( err );
} else {
callback( );
}
});
});
如果要使用RunRequest
,则需要将callback
作为附加参数传递给RunRequest
(因此使用callback
而不是doneRequest
)。
相关文章:
- 异步并行错误
- Fresh Spark Install+Homestead上的Vue异步堆栈跟踪错误
- 异步面板绑定错误
- 在照片查看器(Javascript和jQuery)中异步加载图像时可能出现错误
- 从 Ajax 获取由 ZombieJS 的异步点击事件触发的 Http 错误
- Node.js异步并行“;类型错误:任务不是函数;
- 并行开发同步/阻塞和异步/非阻塞库api的好方法是什么?(JavaScript)
- 当我在异步操作Redux上开始单元测试时,没有定义错误承诺
- 基准测试引发错误的异步与同步代码
- 节点.JS异步并行混淆 |Async.map 返回的内容
- 回调已称为异步并行
- 如何异步并行多个应用程序使用调用
- 为什么异步并行回调会返回意外结果
- API调用与node.js中回调的异步并行
- AJAX调用顺序错误(异步)javascript
- 如何在节点中完成第一个异步并行任务时结束
- 在Node.js中短路非错误异步流的模式
- 使用Async js的异步并行调用
- 在JS中,如何捕获用户定义函数抛出的错误? '异步调用
- 将函数数组传递到异步并行