Node.js + Cheerio:循环内的请求

我正在使用cheerio,请求和Node.js。

当我运行下面的脚本时,它以错误的顺序输出名称。 我相信它是由asynchronous性质引起的,我怎样才能使它在“正确”的顺序工作? 我是否需要使用同步软件包,或者是否有办法以某种方式更改它,以便以同步方式工作?

app.get('/returned', function (req, res) { for (var y = 0; y < 10; y++) { var url = "http://example.com" + y + "/person.html"; request(url, function (err, resp, body) { $ = cheerio.load(body); var links = $('#container'); var name = links.find('span[itemprop="name"]').html(); // name if (name == null) { console.log("returned null"); } else { console.log(name); } }); } }); 

承诺使这相对容易:

 app.get('/returned', function (req, res) { let urls = []; for (let y = 0; y < 10; y++) { urls.push('http://example.com' + y + '/person.html'); } Promise.all(urls.map(function (url) { return new Promise(resolve, reject) { request(url, function (err, resp, body) { if (err) {return reject(err);} let $ = cheerio.load(body); let links = $('#container'); let name = links.find('span[itemprop="name"]').html(); // name resolve({name: name, links: links, url: url}); }); }); }).then(function (result) { result.forEach(function (obj) { if (obj.name == null) { console.log(obj.url, "returned null"); } else { console.log(obj.url, obj.name); } }); }).catch(function (err) { console.log(err); }); }); 

我开始创build一个url的数组,然后我将其映射到一个承诺的数组。 当每个请求都完成时,我解决了承诺的名称,url和链接。 当所有的承诺完成后,我便循环结果,将会按照原来的顺序。 这是并行的。

不,你不应该使用同步包。 最简洁的方法是使用一个成熟的第三方库。

我build议asynchronous。

async.series方法将按照给定的顺序执行所有的请求函数,然后允许你注册一个callback函数,当所有的请求都发生时,或者发生了一个错误。

https://github.com/caolan/async#seriestasks-callback