2017-02-17 4 views
1

Я использую метод водопада асинхронного модуля для запроса sql в узле. Как использовать обратный вызов для отправки двух наборов данных в следующую функцию. Как и в первой функции, которая передает qryUpdateCheck и qryCheckDbl в следующую. Как это будет правильно выполнено.Как использовать обратные вызовы для ожидания двух запросов Асинхронный узел

async.waterfall([ 
    function (callback) { 
     var requestUpdateCheck = new sql.Request([config]); 
     requestUpdateCheck.query("Some qryUpdateCheck", function (err, qryUpdateCheck) { 
      console.log('qryUpdateCheck', qryUpdateCheck);  
     }); 

     var requestCheckDbl = new sql.Request([config]); 
     requestCheckDbl.query("Some qryRequestCheckDbl", function (err, recordset) { 
      console.log('qryCheckDbl', qryCheckDbl);  
     }); 

     callback(null, qryUpdateCheck, qryCheckDbl); 
    }, 
    function (qryUpdateCheck, qryCheckDbl, callback) { 
     console.log('hi from second from qryUpdateCheck', qryUpdateCheck); 
     console.log('hi from second from qryCheckDbl', qryCheckDbl); 
     if ((qryUpdateCheck.length == 1) && (qryCheckDbl.length == 0)) { 
      var requestUpdateLocID = new sql.Request([config]); 

      requestUpdateLocID.query("Last qryUodateLocID", function (err, recordset) { 
       console.log('qryUpdateLocID', recordset); 
       callback(null, recordset); 
      }); 
     } else if ((qryUpdateCheck.length == 0) && (qryCheckDbl.length == 0)) { 
      var requestUpdateLocID = new sql.Request([config]); 
      requestUpdateLocID.query("Insert qry", function (err, recordset) { 
       console.log('qryUpdateLocID', recordset); 
       callback(null, recordset); 
      }); 
     } 
    } 
], function (err, result) { 
    // result now equals 'done' 
    console.log('done', result); 
}); 
+0

Добро пожаловать в StackOverflow! Пожалуйста, найдите время, чтобы прочитать руководство о том, как ответить на вопрос [здесь] (http://stackoverflow.com/help/mcve). –

+1

@ABusyProgrammer вопрос в порядке. – peteb

ответ

1

Я считаю async.auto лучше подобных ситуациях. Вы передаете ему объект с набором функций, и для каждой функции вы можете передавать другие имена функций в качестве зависимостей. Затем он будет запускать любые задачи, которые он может выполнять параллельно, при этом убедитесь, что функции с зависимостями ждут, пока они не будут удовлетворены до их вызова. Это своего рода магия.

var request = new sql.Request([config]); 
async.auto({ 
    // this runs in parallel because it has no dependencies 
    requestUpdateCheck: function(callback) { 
    request.query("Some qryUpdateCheck", callback); 
    }, 
    // this also runs in parallel because it has no dependencies 
    requestCheckDbl: function(callback) { 
    request.query("Some qryRequestCheckDbl", callback); 
    }, 
    // this waits for the first two functions and then executes 
    requestUpdateLocID: ['requestUpdateCheck', 'requestCheckDbl', function(results, callback) { 
    console.log('Results from requestUpdateCheck and requestCheckDbl', JSON.stringify(results, null, 2)); 
    var qryUpdateCheck = results.requestUpdateCheck; 
    var qryCheckDbl = results.requestCheckDbl; 
    if ((qryUpdateCheck.length == 1) && (qryCheckDbl.length == 0)) { 
     request.query("Last qryUodateLocID", function (err, recordset) { 
     console.log('qryUpdateLocID', recordset); 
     callback(err, recordset); 
     }); 
    } else if ((qryUpdateCheck.length == 0) && (qryCheckDbl.length == 0)) { 
     request.query("Insert qry", function (err, recordset) { 
     console.log('qryUpdateLocID', recordset); 
     callback(err, recordset); 
     }); 
    } 
    }] 
}, function(err, results) { 
    console.log('done:', err || results); 
}); 

results будет содержать данные из всех выполненных функций.

Это довольно простой пример, к которому могут относиться, возможно, некоторые аргументы promises.all. Лично я нахожу, что async.auto действительно помогает, когда все усложняется. Поэтому для согласованности я использую его для большинства потоков асинхронного управления и обнаруживаю, что он обрабатывает большинство ситуаций.

+1

Хорошее предложение, это очень похоже на глотку и зависимые задания. – peteb

+0

Я попробовал это, и результаты в requestUpdateLocID возвращаются как undefined – elleven

+0

ahh, вы должны использовать async.js v2 - я на старой версии ... заменяйте обратные вызовы и аргументы результата в функции для 'requestUpdateLocID' - он изменился в v2 - я обновил ответ - он должен быть '(results, callback)' – Robbie

0

Вы можете выполнить вложенный параллельный вызов. Вот пример псевдо с помощью setTimeout:

async.waterfall([ 
    function(callback) { 
     async.parallel({ 
      requestUpdateCheck: function(callback) { 
       setTimeout(function() { 
        callback(null, 'UpdateCheck') 
       }, 500) 
      }, 
      requestCheckDbl: function(callback) { 
       setTimeout(function() { 
        callback(null, 'CheckDbl') 
       }, 500) 
      } 
     }, function(err, result) { 
      // here the parallel op is done 
      callback(err, result); 
     }) 
    }, 
    function(result, callback) { 
     console.log('hi from second from qryUpdateCheck', result.qryUpdateCheck); 
     console.log('hi from second from qryCheckDbl', result.qryCheckDbl); 
     callback(null, result); 
    } 
], function(err, result) { 
    // result now equals 'done' 
    console.log('done', result); 
}); 
+0

Когда я пытаюсь, я получаю «Callback уже был вызван». – elleven

+0

Я действительно не тестировал код - может быть, что имя обратного вызова должно быть изменено. Я поиграю с этим. – brandonscript

+0

@brandonscript, который не должен иметь значения, что 'callback' используется в разных областях здесь, потому что * scope scope * будет использоваться над значением области обратного вызова. IE. Внутренняя область действия самой охватывающей функции будет использоваться, когда есть конфликт. – peteb

Смежные вопросы