问题描述
我有一个URL数组,我想从每个URL中抓取一个html表并将其按与原始数组相同的顺序保存在另一个数组中 。
由于节点的异步性质,我认为它无法按预期工作,因此每次的结果顺序都不同。
我在Google上搜索了很多,并尝试了不同的操作,例如使用自定义async-forEach-function或request-promise而不是request,但是没有任何效果。
const request = require('request'); const rp = require('request-promise'); const cheerio = require('cheerio'); const fs = require('fs'); let verbs = []; let conjugations = []; fs.readFileSync('verbs.txt', 'utf-8').split(/\\r?\\n/).forEach (function(line){ verbs.push(line); }); verbs.forEach((verb) => { const URI = encodeURI("https://ru.wiktionary.org/wiki/" + verb); var options = { uri: URI, transform: function (body) { return cheerio.load(body); } }; rp(options).then(function ($) { let table = $('span#Русский.mw-headline').parent().nextAll('table').first(); conjugations.push(table.text()); console.log(conjugations[0]); }) .catch(function (err) { }); })
1楼
如果顺序很重要,请使用 。
Promise.all()方法返回一个Promise,当作为可迭代对象传递的所有promise已解决或当可迭代对象不包含promise时,该Promise进行解析。 它以第一个承诺被拒绝的理由拒绝。
保持秩序的示例:
const verbs = ["hello", "world", "example"]; let timeout = 2000; const promises = verbs.map(verb=>{ timeout -= 500; return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve(verb); }, timeout); }); }); Promise.all(promises).then(dataArray=>console.log(dataArray));
您的代码的解决方案。
const promises = verbs.map((verb) => {
const URI = encodeURI("https://ru.wiktionary.org/wiki/" + verb);
var options = {
uri: URI,
transform: function(body) {
return cheerio.load(body);
}
};
return rp(options);
})
Promise.all(promises).then(dataArray=>{
dataArray.forEach(function($) {
let table = $('span#Русский.mw-headline').parent().nextAll('table').first();
conjugations.push(table.text());
console.log(conjugations[0]);
})
}).catch(function(err) {});
不利的一面是,如果一个请求失败,它们都会全部失败。
或者,您可以通过使用每个动词的索引来执行类似的操作(使用Promise.all确定何时完成所有操作,但可以忽略该步骤...)
const verbs = ["hello", "world", "example"]; const conjugations = []; let timeout = 2000; const promises = verbs.map((verb, index)=>{ return new Promise((resolve, reject)=>{ setTimeout(function(){ conjugations[index] = verb; resolve(); }, timeout); timeout -= 500; }); }); Promise.all(promises).then(()=>console.log(conjugations));
您的代码示例。
const request = require('request');
const rp = require('request-promise');
const cheerio = require('cheerio');
const fs = require('fs');
let verbs = [];
let conjugations = [];
fs.readFileSync('verbs.txt', 'utf-8').split(/\r?\n/).forEach(function(line) {
verbs.push(line);
});
verbs.forEach((verb, index) => {
const URI = encodeURI("https://ru.wiktionary.org/wiki/" + verb);
var options = {
uri: URI,
transform: function(body) {
return cheerio.load(body);
}
};
rp(options).then(function($) {
let table = $('span#Русский.mw-headline').parent().nextAll('table').first();
conjugations[index] = table.text();
console.log(conjugations[index]);
})
.catch(function(err) {});