javascript - 带有nodejs axios和vanilla javascript中的异步等待模式的数组文件下载器

标签 javascript node.js async-await stream axios

我在用普通 JavaScript 编写并在 NodeJS 中运行的脚本时遇到问题。我想要得到的是:

// Get axios request
  // response stream
  // download file1..........finish
// When file is downloaded 
// go to the next request 

// Get axios request
  // response stream
  // download file2..........finish
// When file is downloaded 
// go to the next request 

我在 Node 和异步等待模式中编写此脚本

// ARRAY OF BOOKS 
ex. [{title: 'awesome book', link: 'http://www.example.com/awesome_book.pdf'},
     {title: 'new book', link: 'http://www.example.com/new.pdf'} ...etc]
const Books = require('./Books');

const fs = require('fs');
const path = require('path');
const axios = require('axios');


// 1)
// loop the array of books and create array of links
let booksLinkinkArray = Books.map( book => book.link);

// 2)
// Function get request with axios
// response is stream
function request (element) {
  try{
    return axios({
      url: element,
      method: "GET",
      responseType: "stream"
    });
  } catch(e) {
    console.log( 'errore: ' + e)
  }
}


// 3)
// Function that downloads the file
async function download(urls) {
  urls.map(async url => {
    try{
      const saveFile = await request(url);
      let file = url.split('/')[3];
        console.log(file + ' :  ' + 'init download');
      let download = fs.createWriteStream(path.join(__dirname, 'books_dir', file));
      saveFile.data.pipe(download);
      console.log(file + ' :  ' + 'downloaded')

    } catch(e) {
      console.log( 'error: ' + e)
    }

  }) }

download(booksLinkinkArray);

这个脚本没问题,但是请求循环太快,文件下载重叠为:

// get request
// response
//download file init
// get request
// response
//download file init
ect...

file 1.......
file 2........
file 1...........
file 2..........
file 2.............. finish
file 1.............. finish

是否有一种方法来管理流,以便仅在所有 block 从流中排出后才进行调用?

感谢您的回复

最佳答案

async download(urls){
  for(const url of urls) {
     const saveFile = await request(url);
     const file = url.split('/')[3];
     const download = fs.createWriteStream(path.join(__dirname, 'books_dir', file));
     await new Promise((resolve, reject)=> {
        saveFile.data.pipe(download);
        download.on("close", resolve);
        download.on("error", console.error);
     });
  }
}

关于javascript - 带有nodejs axios和vanilla javascript中的异步等待模式的数组文件下载器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58907106/

相关文章:

javascript - JavaScript 如何确定何时为函数调用提供 "this"上下文?

javascript - 在 ng-repeat 生成的 <ul> 列表中使用 ng-model

javascript - 使用 Nodemon 在 Node.js v6.2.0 上安装 Babel V6.x ES7 Async/Await

C# 暂停循环并在单击按钮后继续

javascript Node.js 异步等待电子

javascript - react hooks 和 react class 的性能对比

javascript - 使用 jQuery Mobile 和 $(document).ready 与 PhoneGap Build 和 document.addEventListener ("deviceready")

node.js - 使用 ember 和 ember-cli 编辑 Handlebars 模板

node.js - 如何使用指示性添加唯一规则?

c# - 异步 TCP 操作期间的 AccessViolation