【问题标题】:JS return doesn't wait for await [duplicate]JS返回不等待等待[重复]
【发布时间】:2018-06-27 01:32:45
【问题描述】:

我正在尝试使用异步等待。

我的应用是这样开始的

axios.get(`${ROOT_URL}/ccidxann.php`)
  .catch(err => console.error('axios error get', err))
  .then(async res => {
    const html = res.data
    const jobList = await getJobList(html)
    console.log(' after each jobList', jobList)
    // jsonfile.writeFileSync('jobs.json', jobList, { flag: 'a' })
  })
  .catch(err => console.error(err))

问题是jobList 总是作为空数组返回。 这是getJobList 函数

async function getJobList (html) {
  const jobList = []

  const dom = new JSDOM(html)
  const { window } = dom
  const $ = require('jquery')(window)
  const jobsInDom = $('table').first().find('td > a')

  // AWAIT HERE
  await jobsInDom.each(async function (index, jobElem) {
    const name = $(jobElem).text()
    const url = $(jobElem).attr('href')
    // Another AWAIT HERE
    const jobDetailsHTML = await getJobDetailsHTML(`${ROOT_URL}/${url}`)
      .catch(err => console.error('getJobDetailsHTML err', err))
    const domDetails = new JSDOM(jobDetailsHTML)
    const { window: windowDetails } = domDetails
    const $details = require('jquery')(windowDetails)
    const jobDetailsHTMLBody = $details('body').prop('outerHTML')
    jobList.push({
      _id: url,
      name,
      detailsHTML: jobDetailsHTMLBody
    })
    console.log('in each jobList', jobList)
  }) //each
  return jobList
}

如你所见,我将async关键字放在它前面,

我已经将async关键字放在each的回调中

并将await 放在所有异步操作的前面。

each 的回调中的console.log 打印填充了值的数组

但似乎returneach 之前有效

即使前面有await关键字。

还有getJobDetailsHTML 以防万一。这是一个简单的功能,似乎工作得很好

async function getJobDetailsHTML (url) {
    // ANOTHER AWAIT HERE
    return await axios.get(url).data
}

【问题讨论】:

    标签: javascript ecmascript-2017


    【解决方案1】:

    我认为jobsInDom.each 是同步函数,所以将 await 放在前面不会给你想要的效果。因此,您需要以某种方式获得在所有作业的处理完成时解决的承诺,如下所示:

      // handles one element and returns promise
      const jobHandler = async jobElem => {
        const name = $(jobElem).text()
        const url = $(jobElem).attr('href')
        const jobDetailsHTML = await getJobDetailsHTML(`${ROOT_URL}/${url}`)
          .catch(err => console.error('getJobDetailsHTML err', err))
        const domDetails = new JSDOM(jobDetailsHTML)
        const { window: windowDetails } = domDetails
        const $details = require('jquery')(windowDetails)
        const jobDetailsHTMLBody = $details('body').prop('outerHTML')
        jobList.push({
          _id: url,
          name,
          detailsHTML: jobDetailsHTMLBody
        })
        console.log('in each jobList', jobList)
      }
    
      const promises = [];
    
      // start processing of each element
      jobsInDom.each((index, jobElem) => promises.push(jobHandler(jobElem));
    
      // wait for processing of all job elements
      await Promise.all(promises);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-13
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 1970-01-01
      • 2013-08-06
      • 2019-02-06
      • 1970-01-01
      相关资源
      最近更新 更多