0

我想请求一个网站 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为不同。

4

2 回答 2

1

你不想同步运行它们——你想同步它们——它们是不同的。

您可以将一系列承诺与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
});

请注意,除此之外,您的代码仍然不是很高效 - 如果 10 个请求中有 9 个非常快并且需要一分钟会发生什么?您将只有一个传出请求。您可以使用类似的库bluebird,该库具有更有效Promise.map的方法和并发参数。

于 2016-05-04T08:38:42.517 回答
0

这可能在不使用生成器的情况下工作

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

这背后的想法是建立承诺链,以便下一个将放弃前一个完成

于 2016-05-04T08:51:46.570 回答