Javascript.Run Multi обещания Синхронно

Я хочу запросить сайт 40 раз.

Я хочу, чтобы это было синхронно, как 10 запросов 4 раза.

Это мой код на 1 запрос - 40 раз:

'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);
        }
    });

Я могу сделать массив обещаний, но я не могу понять, как изменить значение q Быть другим.

2 ответа

Решение

Вы не хотите запускать их синхронно - вы хотите синхронизировать их - они разные.

Вы бы использовали массив обещаний вместе с Promise#all, Когда вы создаете обещание, действие уже выполняется - только yield синхронизирует вещи.

Вы можете сделать 10 запросов одновременно так:

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
});

Обратите внимание, что в дополнение к этому ваш код все еще не очень эффективен - что произойдет, если 9 из 10 запросов действительно быстрые, а один занимает минуту? У вас будет только один исходящий запрос. Вы можете использовать библиотеку как bluebird который имеет более эффективный Promise.map метод с параметром параллелизма.

Это может работать без использования генераторов

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)
}

Идея заключается в том, чтобы построить цепочку обещаний, чтобы следующий отказался от завершения предыдущего.

Другие вопросы по тегам