for循环内的异步函数等待循环完成,然后执行下一个操作

时间:2019-06-30 02:52:32

标签: javascript asynchronous

我正在尝试遍历Reddit链接列表,并一步一步下载它们。

我有一个异步功能,可以检索imgur相册图像并下载它们

async function getAlbum(sub,title,id,psub,auth) {

   let p = {}
   let alburls  = []
   let result = await   getAlbumImages(id)

   let re = result.data.data.images

   for(v of re)
   {
    var ext = v.link.split('.').pop();
    if(psub == true) {
      file_name = title + ' '+ 'U-- ' +auth+ '.'+ext
    } else {
      file_name = title+ '.' +ext
    }
      await downloadFile( v.link,file_name)
   }
    console.log({re});

}

此方法下载检索到的文件

var downloadFile =  async (link,filename) => {

  request
    .get(link)
    .on('error', function(err) {
      console.log(err)
    })
    .pipe(writeFile(filename,dir))
    .on('finish', () => {
          console.log('Downloaded Image: ' + filename);

      });
 }

两个函数都可以正常工作,但是这里的问题是执行顺序。

第一个函数中的console.log({re})难道不是在downloadFile函数中的console.log之后吗?我正相反。 我想在for循环完成后执行一个功能

1 个答案:

答案 0 :(得分:2)

您的downloadFile函数返回的诺言将立即解决,因为它不等待任何异步操作。这可以通过使用返回承诺的请求库来解决,但我假设您使用的不是。

您可以将该请求包装在一个承诺中,以解决回调中的承诺。这称为“承诺”回调。

async function getAlbum(sub,title,id,psub,auth) {

   let p = {}
   let alburls  = []
   let result = await   getAlbumImages(id)

   let re = [{}

   for(v of re)
   {
    var ext = v.link.split('.').pop();
    if(psub == true) {
      file_name = title + ' '+ 'U-- ' +auth+ '.'+ext
    } else {
      file_name = title+ '.' +ext
    }
      await downloadFile( v.link,file_name)
   }
    console.log({re});

}

var downloadFile =  async (link,filename) => {
  return new Promise((resolve, reject) => {
    request
      .get(link)
      .on('error', function(err) {
        console.log(err)
        reject()
      })
      .pipe(writeFile(filename,dir))
      .on('finish', () => {
            console.log('Downloaded Image: ' + filename);
            resolve()
        });
    }
 }