2012-09-13 58 views
0

在這裏,我試圖用Async.js的參數來創建一個函數數組。異步並行錯誤?

該數組包含RunRequest的實例,應該在MakeRequest的循環內設置,就在我嘗試將函數數組傳遞給Async之前。

所以當我將它傳遞給RunRequest時請求[i]中的請求很好,但在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); 
     }); 
    }); 
} 

回答

0

這是一個範圍的問題。當循環結束變量i設置爲request.length時,所以request[i]undefined

與匿名函數一樣,包裝你的代碼:

甚至更​​好(創建匿名函數時避免不必要的開銷):

var requestArray = []; 
request.forEach(function(el) { 
    console.log('run request was called'); 
    // the other code goes here, use el instead of request[i] 
}); 

編輯回調不叫,因爲您沒有正確定義數組中的函數。你將不得不重構你的代碼一點,這樣讓我告訴你應該如何:

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)。

+0

這工作好多了,但不幸的是,Async.parallel回調仍然沒有被稱爲... –

+0

@JoshElias我已經更新了答案。 – freakish

1

這僅僅是一個在黑暗中拍攝:

我認爲這個問題是你如何調用RunRequestMakeRequest。在第一個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)); 
}