2013-06-27 2 views
1

Update 2nodejs async.waterfall метод

Полный код листинга

var request = require('request'); 
var cache = require('memory-cache'); 
var async = require('async'); 

var server = '172.16.221.190' 
var user = 'admin' 
var password ='Passw0rd' 
var dn ='\\VE\\Policy\\Objects' 

var jsonpayload = {"Username": user, "Password": password} 


async.waterfall([ 
    //Get the API Key 
    function(callback){ 
     request.post({uri: 'http://' + server +'/sdk/authorize/', 
       json: jsonpayload, 
       headers: {'content_type': 'application/json'} 
      }, function (e, r, body) { 
      callback(null, body.APIKey); 
     }) 
}, 
    //List the credential objects 
    function(apikey, callback){ 
     var jsonpayload2 = {"ObjectDN": dn, "Recursive": true} 
     request.post({uri: 'http://' + server +'/sdk/Config/enumerate?apikey=' + apikey, 
       json: jsonpayload2, 
       headers: {'content_type': 'application/json'} 
     }, function (e, r, body) { 

      var dns = []; 
      for (var i = 0; i < body.Objects.length; i++) { 
       dns.push({'name': body.Objects[i].Name, 'dn': body.Objects[i].DN}) 
      } 

      callback(null, dns, apikey); 
     }) 

    }, 
    function(dns, apikey, callback){ 
     // console.log(dns) 

     var cb = []; 

     for (var i = 0; i < dns.length; i++) { 

     //Retrieve the credential 
     var jsonpayload3 = {"CredentialPath": dns[i].dn, "Pattern": null, "Recursive": false} 
      console.log(dns[i].dn) 
     request.post({uri: 'http://' + server +'/sdk/credentials/retrieve?apikey=' + apikey, 
      json: jsonpayload3, 
      headers: {'content_type': 'application/json'} 
     }, function (e, r, body) { 
     // console.log(body) 
      cb.push({'cl': body.Classname}) 
      callback(null, cb, apikey); 
      console.log(cb) 
     }); 
     } 


    } 
], function (err, result) { 
// console.log(result) 
    // result now equals 'done' 
});  

Update:

Я строю небольшое приложение, которое нужно сделать несколько вызовов HTTP на внешний API и объединяет результаты в один объект или массив. например

  1. Подключение к конечной точке и получить ключ аутентификации - передать аутентификации ключа к шагу 2
  2. Подключения к конечной точке с помощью ключа аутентификации и получить результаты JSON - создать объект, содержащий итоговые результаты и перейти к шагу 3.
  3. итерацию по итоговым результатам прошедшего объекта и API вызовов для каждого элемента в объекте для получения подробной информации для каждой сводной строки
  4. Создайте единую структуру данных JSON, которая содержит сводную и подробную информацию.

Оригинальный вопрос ниже описывает, что я пробовал до сих пор!

Оригинал Вопрос:

будет поддерживать метод async.waterfall несколько функций обратного вызова?

i.Eterate over array, переданный из предыдущего элемента в цепочке, затем вызывает несколько HTTP-запросов, каждый из которых будет иметь свои собственные обратные вызовы.

например,

sync.waterfall([ 

    function(dns, key, callback){ 

     var cb = []; 

     for (var i = 0; i < dns.length; i++) { 

     //Retrieve the credential 
     var jsonpayload3 = {"Cred": dns[i].DN, "Pattern": null, "Recursive": false} 
      console.log(dns[i].DN) 
     request.post({uri: 'http://' + vedserver +'/api/cred/retrieve?apikey=' + key, 
      json: jsonpayload3, 
      headers: {'content_type': 'application/json'} 
     }, function (e, r, body) { 
      console.log(body) 
      cb.push({'cl': body.Classname}) 
      callback(null, cb, key); 

     }); 
     } 


    } 
+0

Нет. Если вы переформулируете вопрос, описывающий, что вы пытаетесь сделать, что вы пытались и как оно терпит неудачу, более вероятно, что кто-то может дать вам более полезный ответ. –

+0

похоже, что вы потерялись в обратном вызове ада. – Gntem

+0

ОК, поэтому я уточнил вопрос с более подробной информацией о том, чего я пытаюсь достичь. – user1513388

ответ

2

Будем надеяться, я правильно понял ваш вопрос. Мне кажется, вы хотите называть api для каждого элемента в dns и должны знать, когда они будут сделаны. async.waterfall обычно используется, когда у вас есть цепочка функций, которая использует результат предыдущей функции. В вашем случае я могу только видеть, что вам нужно использовать результат из всех api-вызовов за один обратный вызов. И так как вы также хотите создать новый массив, я бы использовал async.map.

Update:

Если вы хотите, чтобы сделать петлю внутри async.waterfall, async.each/карта является оружием выбора. Приведенный ниже код вызовет обратный вызов водопада при вызове каждого dns.

async.waterfall([ 
    // ..., 
    function(dns, apikey, callback){ 
    async.map(dns, function (item, next) { 
     var jsonpayload3 = { 
     Cred: dns[i].DN, 
     Pattern: null, 
     Recursive: false 
     }; 

     request.post({ 
     uri: 'http://' + vedserver +'/api/cred/retrieve?apikey=' + key, 
     json: jsonpayload3, 
     headers: {'content_type': 'application/json'} 
     }, function (e, r, body) { 
     next(e, { cl: body.Classname }); 
     }); 
    }, 
    callback); 
    }], 
    function (err, result) { 
    // result now looks like [{ cl: <body.Classname> }] 
    }); 
+0

Большое спасибо за вашу помощь здесь, хотя я не совсем уверен, как ваше предложение выше будет реализовано. Я обновил свой вопрос с полным списком кодов, чтобы вы могли видеть, что я пытаюсь сделать! – user1513388

+0

Извините, что приклеил неправильный фрагмент кода в моем обновлении раньше - можете ли вы показать мне, где я должен добавить метод async.map, пожалуйста. – user1513388

+0

А теперь это имеет больше смысла. Обновлен ответ с тем, как вы вставляете код в свой код. –