2016-04-09 2 views
1

Я хотел бы сделать синхронный вызов http с помощью Q Promises, у меня есть 100 студентов, которые мне нужны для каждого из них, чтобы взять некоторые данные с другой платформы и сделать это, я пытался через Q Promises, но не похоже, что он делает синхронно.Как сделать синхронный HTTP-вызов с помощью обещаний в Nodejs

Как я убеждаюсь, что еще один вызов не производится один раз один закончил с разбора это ответ и вставки в MongoDB:

мой код до сих пор выглядит следующим образом:

var startDate = new Date("February 20, 2016 00:00:00"); //Start from February 
var from = new Date(startDate).getTime()/1000; 
startDate.setDate(startDate.getDate() + 30); 
var to = new Date(startDate).getTime()/1000; 

iterateThruAllStudents(from, to); 

function iterateThruAllStudents(from, to) { 
    Student.find({status: 'student'}) 
     .populate('user') 
     .exec(function (err, students) { 
      if (err) { 
       throw err; 
      } 

      async.eachSeries(students, function iteratee(student, callback) { 
        if (student.worksnap.user != null) { 
         var worksnapOptions = { 
          hostname: 'worksnaps.com', 
          path: '/api/projects/' + project_id + '/time_entries.xml?user_ids=' + student.worksnap.user.user_id + '&from_timestamp=' + from + '&to_timestamp=' + to, 
          headers: { 
           'Authorization': 'Basic xxxx=' 
          }, 
          method: 'GET' 
         }; 

         promisedRequest(worksnapOptions) 
          .then(function (response) { //callback invoked on deferred.resolve 
           parser.parseString(response, function (err, results) { 
            var json_string = JSON.stringify(results.time_entries); 
            var timeEntries = JSON.parse(json_string); 
            _.forEach(timeEntries, function (timeEntry) { 
             _.forEach(timeEntry, function (item) { 
              saveTimeEntry(item); 
             }); 
            }); 
           }); 
           callback(); 
          }, function (newsError) { //callback invoked on deferred.reject 
           console.log(newsError); 
          }); 
        } 
       }); 

function saveTimeEntry(item) { 
    Student.findOne({ 
      'worksnap.user.user_id': item.user_id[0] 
     }) 
     .populate('user') 
     .exec(function (err, student) { 
      if (err) { 
       throw err; 
      } 
      student.timeEntries.push(item); 
      student.save(function (err) { 
       if (err) { 
        console.log(err); 
       } else { 
        console.log('item inserted...'); 
       } 
      }); 

     }); 
} 

function promisedRequest(requestOptions) { 
    //create a deferred object from Q 
    process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; 
    var deferred = Q.defer(); 
    var req = http.request(requestOptions, function (response) { 
     //set the response encoding to parse json string 
     response.setEncoding('utf8'); 
     var responseData = ''; 
     //append data to responseData variable on the 'data' event emission 
     response.on('data', function (data) { 
      responseData += data; 
     }); 
     //listen to the 'end' event 
     response.on('end', function() { 
      //resolve the deferred object with the response 
      console.log('http call finished'); 
      deferred.resolve(responseData); 
     }); 
    }); 

    //listen to the 'error' event 
    req.on('error', function (err) { 
     //if an error occurs reject the deferred 
     deferred.reject(err); 
    }); 
    req.end(); 
    //we are returning a promise object 
    //if we returned the deferred object 
    //deferred object reject and resolve could potentially be modified 
    //violating the expected behavior of this function 
    return deferred.promise; 
} 

Любой мог скажите мне, что мне нужно сделать для достижения таких вещей? Возможно ли это, так что я знаю, когда все http-звонки закончены, и вставка выполняется для всех ...

+0

Если вы хотите обработать одного ученика за другим, используйте 'eachSeries' вместо' each' и 'callback', это второй аргумент в вашем' iteratee'. Вызывать «обратный вызов» при завершении обработки –

+0

жаль, что я новичок в обратных вызовах, обещаниях, как это сделать? где я могу добавить его? –

+0

@DimaFitiskin Я обновил свой код, вы имели в виду вот так, добавив обратный вызов? –

ответ

1

Я бы отказался от вашего текущего подхода и использовал запрос npule nodule request-prom. https://www.npmjs.com/package/request-promise

Это очень популярный и зрелый.

rp('http://your/url1').then(function (response1) { 
    // response1 access here 
    return rp('http://your/url2') 
}).then(function (response2) { 
    // response2 access here 
    return rp('http://your/url3') 
}).then(function (response3) { 
    // response3 access here 
}).catch(function (err) { 
}); 

Теперь вам просто нужно преобразовать это в какой-то итерации для 100 запросов, которые вы хотите, и работа будет сделано.

+0

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

+0

ok, дайте мне пример из 3 URL-адресов, поэтому я вижу, где они похожи для итеративных целей. – danday74

+0

Не имеет значения URL-адрес, вы можете просто написать какой-либо URL-адрес, я просто хочу посмотреть, как бы вы преобразовали это в foreach или smth ... Итак, я вижу. –

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

  • Нет связанных вопросов^_^