异步等待forEach循环仍然异步运行

时间:2018-04-24 17:34:25

标签: javascript node.js asynchronous

首先,我确实阅读了类似的问题,但仍然看不出我犯了哪些错误。

这是我的代码:

digitlead.com
google.com
georgiancollege.ca
youtube.com
    []
true
true
true
true

工作原理:

用户传递了一系列网站,我想验证他们是否是有效的网站,而不是浪费资源和阻止其他错误。现在到控制台:

for

如您所见,它首先打印出网站数组,然后打印出响应。所以它仍然是异步的。我如何让它等待?我按照许多帖子的建议将循环从forEach更改为await,我使用async function validateWebsites(website) { var result = url.parse(`http://${website}`); // TODO figure out if filtering all the subpages is a good idea. console.log(result.hostname); return await fetch(`http://www.${result.hostname}`) .then(()=>console.log(true)) .catch(()=>console.log(false)); } 并返回一个承诺。那么我还需要做些什么呢?

编辑:

我试着这样做:

readFileSync

但它并没有改变任何东西

我找到了一个名为.sortBy(p -> -p.getAge())... 的函数。这或多或少都是我所寻找的,但能够呼叫不同的网站。

2 个答案:

答案 0 :(得分:0)

以下是获取所有有效网站的方法 您的validateWebsites函数的问题在于它返回了承诺wchih正在解析为undefined,这要归功于承诺链和您的登录

使用forEach过滤数组也是不必要的 但如果你想要你可以做这样的事情

websites.forEach(async website => {
    i++;
    if (await validateWebsites(website) === false) { // now value is Boolean instead of Promise
        wrongWebsites.push(i);
    }
});

另请注意,如果您使用具有异步函数的全局i来跟踪索引,则可能会导致许多错误。

但是我觉得这个灵魂应该让你满意

async function validateWebsites(website) {
  var result = url.parse(`http://${website}`)
  return fetch(`http://www.${result.hostname}`)
    .then(() => true) // async function returns promise
    .catch(() => false)
}

const websites = ['digitlead.com',
  'google.com',
  'georgiancollege.ca',
  'youtube.com',
  '111.1',
  'foobarbaz']

async function filter(array, func) {
  const tmp = await Promise.all( // waits for all promises to resolve
    array.map(func) // evecutes async function and stores it result in new array then returns array of promises
  ) 
  return array.filter((_, i) => tmp[i]) // removes invalid websites
}

const validWebsites = filter(websites, validateWebsites)

validWebsites.then(console.log) 

获取无效网站的索引

async function filter(array, func) {
  const tmp = await Promise.all(array.map(func))
  return tmp
         .map((x, i) => !x && i) // flip true to false and asign index when x is false
         .filter(x => x !== false) // return indexes
}

答案 1 :(得分:-1)

destoryer说你应该这样做:

websites.forEach(async website => {
    i++;
    if (await validateWebsites(website) === false
    ) {
        wrongWebsites.push(i);
    }
});

但仅此一点是有问题的,因为您已将async函数包装在try/catch中以处理其错误。所以更像是这样的事情:

websites.forEach(async website => {
    i++;

    try {
      const validSites = await validateWebsites(website); 
      if (validSites === false) {
        wrongWebsites.push(i);
      }
    } catch(e) {
        // handle e
    }
})