承诺所有带有内部功能的执行

时间:2018-11-10 15:50:06

标签: javascript node.js

我想立即检索到不同的HTML正文,并在所有结果可用时立即处理该内容。

我的回调解决方案看起来像这样(可能只有在思路不清楚时才与阅读相关,否则请跳过;)):

const request = require('request')

const argLength = process.argv.length
const result_array = []
let counter = 0

function executeRequest () {
  for (start = 2; start <= argLength - 1; start++) {
    const copy = start

    function callback (error, res, body) {
      const startCopy = copy
      if (error) {
        console.log('error')
        return
      }
      result_array[startCopy - 2] = body.toString().length
      counter++
      if (counter === argLength - 2) {
        console.log(result_array)
      }
    }

    request(process.argv[start], callback)
  }
}

executeRequest()

现在,我尝试使它与这样的Promise一起运行:

const httpRequest = require('request')
const argumentLength = process.argv.length

function fillURLArray () {
  resultArray = []
  for (start = 2; start < argumentLength; start++) {
    resultArray[start - 2] = process.argv[start]
  }
  return resultArray
}

const urls = fillURLArray()

let counter = 0

function readHttp () {
  const resultArray = []
  Promise.all(urls.map(url => httpRequest(url, (error, res, body) => {
    console.log(body.toString())
    resultArray[counter++] = body.toString()
  }))).then(value => {
    console.log('promise counter: ' + counter++)
    console.log(resultArray)
    console.log('called')
  })
}

readHttp()

我已经用不同的Promise链尝试了几次尝试,但是每次我得到的不是结果就是一个空数组。因此很显然,.then()函数是在数组实际被填充之前被调用的(至少我猜是这样,因为console.log(body.toString())似乎在以后会打印内容)

有什么想法可以用诺言来解决吗?

谢谢

2 个答案:

答案 0 :(得分:1)

request不会返回Promise对象,因此创建了一个方法来返回您执行Promise.all的Promise对象。

function requestPromise(url){
  return new Promise((resovle,reject) => {
     httpRequest(url, (error, res, body) => {
      if(err){
         reject(err);
      }
      resolve(body.toString());
  });
  });
}


function readHttp () {
  const resultArray = []
  Promise.all(urls.map(url => requestPromise(url))).then(values => {
    console.log("counter => ",values.length);
    resultArray = resultArray.concat(values);
    console.log("values=> ",values);
    console.log("resultArray=> ",resultArray);
  });
}

答案 1 :(得分:1)

httpRequest不会返回承诺,因此您必须自己做一个,也不需要resultArray

 const makeRequest = url => new Promise((resolve, reject) => httpRequest(url, (error, res) => error ? reject(error) : resolve(res)));

 Promise.all(urls.map(makeRequest))
   .then(result => {         
     console.log(result.map(res => res.body.toString()));
     console.log('called');
   });