2016-05-04 16 views
0

Ich möchte eine Website für 40 Mal anfordern.Javascript.Run Multi verspricht synchron

Ich möchte das synchron sein, wie 10 Anfragen 4 mal.

Dies ist mein Code für 1 Anfrage - 40mal:

'use strict'; 

var request = require('request'); 
var co = require('co'); 


function callUrl(url) { 
    return new Promise((resolve, reject) => { 
     request.get(url, (e, r, b) => { 
      if (e) reject(e) 
      else 
       resolve(`Response from ${url}`); 
     }); 
    }) 
} 


co(function*() { 
     for (var i = 1; i < 41; i++) { 
      let rs = yield callUrl('https://www.google.com/?q=' + i); 
      // let rs = yield makeUrls(10,i); 
      console.log(rs); 
     } 
    }); 

ich eine Reihe von Versprechungen machen kann, aber ich kann es nicht herausgefunden, wie der Wert von q zu ändern, anders zu sein .

+0

tun Sie passieren wollen beenden das Ergebnis jedes Versprechens zum nächsten oder feuere sie synchron ohne direkte Beziehung? –

+0

Ich möchte sie in einer Kette feuern, ich möchte nicht jede URL durchlaufen. Stellen Sie sich vor, ich muss 10.000 Anfragen machen. Ich möchte mehrere Versprechen gleichzeitig ablegen. Ich möchte sie nicht alle gleichzeitig haben, weil ich den Server DDOS haben könnte. –

Antwort

1

Sie möchten sie nicht synchron laufen lassen - Sie wollen sie synchronisieren - die sind unterschiedlich.

Sie würden eine Reihe von Versprechen zusammen mit Promise#all verwenden. Wenn Sie ein Versprechen erstellen, wird die Aktion bereits ausgeführt - nur yield synchronisiert die Dinge.

können Sie bis zu 10 Anfragen stellen einmal wie so:

co(function*() { 
    for (var i = 1; i < 41;) { 
     var promises = []; 
     for(var lim = i + 10; i < Math.max(lim, 41); i++) { 
      promises.push(callUrl('https://www.google.com/?q=' + i)); 
     } 
     let rs = yield Promise.all(promises); // wait for everything 
     console.log(rs); // an array of 10 results 
}); 

Beachten Sie, dass die zusätzlich zu Ihrem Code noch nicht sehr effizient ist - was ist, wenn 9 von 10 Anfragen geschieht wirklich schnell sind und man nimmt eine Minute? Sie haben nur eine ausgehende Anfrage. Sie können eine Bibliothek wie bluebird verwenden, die eine effizientere Promise.map-Methode mit einem Parallelitätsparameter aufweist.

+0

Es funktioniert, danke. Aber bitte erklären Sie mir die 'for' Schleife, die die Versprechen in ein Array drückt. Ich kann nicht herausfinden, warum 'j ++' –

+0

Sie haben Recht, ich brauche eigentlich keinen zweiten Zähler (ich tat es, seit ich j in der CallUrl verwendet). –

0

diese w/o mit Generatoren funktionieren könnte

const urls = [/*array of urls*/]; 
const initialPromise = request[urls[0]]; 
let promise = initialPromise; 
for(let i= 1; i<40;i++){ 
    let thenFunction = response => { 
    //do something with the response 
    return request(urls[i]) 
    } 
    promise = promise.then(thenFunction) 
} 

die Idee dahinter ist, die Kette von Versprechen zu bauen, so dass der nächste für die vorherige waif wird

+0

OP-Code tut dies derzeit bereits mit Korotinen. –

+0

Dies war ein Generator-les-Ansatz, falls er interessiert war –