Próbuję wykonać kilka żądań asynchronicznych i próbując uzyskać wyjście za pomocą obietnic.

Jeśli mam wiele prośby w kolejce Q.All (obietnice) .Na () funkcja nie wydaje się działać. W przypadku pojedynczego żądania obietnice są rozwiązane. Przykładowy kod jest tutaj.

var request = require('request');
var Q = require('q');

var sites = ['http://www.google.com', 'http://www.example.com', 'http://www.yahoo.com'];
// var sites = ['http://www.google.com']

var promises = [];

for (site in sites) {
  var deferred = Q.defer();
  promises.push(deferred.promise);
  options = {url: sites[site]};

  request(options, function (error, msg, body) {
    if (error) {
      deferred.reject();
    }

    deferred.resolve();
  });
}

Q.all(promises).then (function () {
  console.log('All Done');
});

Co tu robię źle?

Surya.

1
Surya 14 sierpień 2014, 21:31

3 odpowiedzi

Najlepsza odpowiedź

Oto, co zrobiłeś w scenariuszu, jest to cały kod:

var Q = require('q');
var request = Q.nfbind(require('request'));

var sites = ['http://www.google.com', 'http://www.example.com', 'http://www.yahoo.com'];
var requests = sites.map(request); 

Q.all(requests).then(function(results){
   console.log("All done") // you can access the results of the requests here
});

Teraz dlaczego:

  • Zawsze proponujemy na najniższym poziomie, proponuje samą prośbę, a nie konkretne żądania. Preferuj automatyczne promisowanie ręcznego promisji, aby nie robić głupich błędów.
  • Podczas pracy na kolekcjach - przy użyciu {x0}} jest łatwiejszy niż ręcznie iterowanie ich, ponieważ produkujemy dokładnie jedną akcję na URL tutaj.

To rozwiązanie jest również krótkie i wymaga minimalnego gniazda.

3
Benjamin Gruenbaum 14 sierpień 2014, 17:43

Nie używaj for..in, aby iterować w tabliczce. Co faktycznie jest ustawione site do 0, 1, 2 i to nie działa bardzo dobrze. Użyj innej formy iteracji, jak regularny for pętla lub Array.prototype.forEach

sites.forEach(function (site) {                                                 
  var deferred = Q.defer();                                                     
  promises.push(deferred.promise);                                               
  options = {url: site};       
0
Explosion Pills 14 sierpień 2014, 17:39

Problem polega na tym, że zmienisz wartość deferred na każdym kleszczeniu pętli {x1}}. Więc jedyna obietnica, która jest faktycznie rozwiązana w twoim przykładzie, jest ostatnim.

Aby go naprawić, należy przechowywać wartość deferred w pewnym kontekście. Najprostszym sposobem na to jest użycie {{x1} } Metoda zamiast for pętla:

sites.forEach(function (site){
  var deferred = Q.defer();
  var options = {url: sites[site]};
  promises.push(deferred.promise);

  request(options, function (error, msg, body) {
    if (error) {
      deferred.reject();
    }

    deferred.resolve();
  });
})

A ty również brakowało var deklarowanie zmiennej options. W JavaScript oznacza Deklarację zmiennej globalnej (lub zmiennej o szerokości modułu w node.js).

0
Leonid Beschastny 14 sierpień 2014, 17:39