仅在流结束后解决承诺

时间:2019-01-13 19:35:26

标签: javascript node.js

我想知道如何在第一个流结束后才能解析并获取下一个数组值,我当前的代码只是对所有网址执行流,而不是一个一个地


const downloadUrl = (url) => {
console.log(url);
console.log("Started :" + url.name);
const writer = fs.createWriteStream(url.name);
return new Promise(resolve => {
    return axios({
      url: url.url,
      responseType: 'stream',
    })
      .then(response => {
        const totalLength = response.headers['content-length'];
        const stream = response.data;
        let chunksDone = 0;

        stream.on('data', (chunk) => {
          const chunkLength = chunk.length;
          chunksDone += chunkLength;
          const percent = ((chunksDone / totalLength) * 100).toFixed(2);
          printProgress(url.name, percent)
          writer.write(new Buffer(chunk));
        })

        return streamToPromise(stream);
      })
      .then(() => {
        debugger;
        writer.end();
      })
      .catch(log);
  })
}

const streamToPromise = (stream) => {
  return new Promise(function (resolve, reject) {
    stream.on("end", resolve);
    stream.on("error", reject);
  })
}

const urls = ['some.mp3','someother.mp3'];
const promise = urls.reduce(function (acc, item) {
      return downloadUrl(item)
    }, Promise.resolve);

1 个答案:

答案 0 :(得分:1)

return new Promise(resolve => {
    return axios({
      url: url.url,
      responseType: 'stream',
    })
      …
}

这将返回一个无法解决的承诺。直接放下new Promise包装器和return axios(…

const promise = urls.reduce(function (acc, item) {
      return downloadUrl(item)
    }, Promise.resolve);

这不等待任何承诺。看来您要去的地方:

const promise = urls.reduce(function (acc, item) {
  return acc.then(() => downloadUrl(item));
}, Promise.resolve());

此外,在写入之前,无需将chunk复制到new Buffer