0

ここでは、Async.js への引数を持つ関数の配列を作成しようとしています。

この配列は、関数配列を Async に渡す直前に、MakeRequest のループ内で設定されることになっている RunRequest のインスタンスで構成されています。

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);
        });
    });
}
4

2 に答える 2

1

これは暗闇の中でのショットです。

RunRequest問題は、内部をどのように呼び出すかだと思いますMakeRequest。最初のforループ内では、無名関数内で繰り返しrequest使用していますが、次の反復で変更され、実際に実行されると現在のスコープが失われます。request[i]iRunRequest

再現するのは難しいですが、これを試してください:

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));
}
于 2012-09-13T07:48:16.957 に答える
0

これはスコープの問題です。ループが終了すると、変数がiに設定されます。request.lengthrequest[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]
});

編集配列内の関数を正しく定義していないため、コールバックは呼び出されません。コードを少しリファクタリングする必要があるため、どのようにするかをお見せしましょう。

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に渡す必要があります (の代わりに使用します)。callbackRunRequestcallbackdoneRequest

于 2012-09-13T07:57:16.693 に答える