当前位置: 代码迷 >> JavaScript >> Web搜寻器的异步请求
  详细解决方案

Web搜寻器的异步请求

热度:96   发布时间:2023-06-07 16:36:00.0

我有一个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) { }); }) 

如果顺序很重要,请使用 。

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) {});
  相关解决方案