簡體   English   中英

Node.js下載文件-並非所有請求都能解決,Promise.all不會觸發

[英]Node.js downloading files - not all requests resolve, Promise.all doesn't fire

我正在嘗試使用request,fs-extra在Node.js中編寫程序,並承諾下載Amazon S3上提供的一系列文件。

對於較小的文件,該程序可以運行。 但是,如果有五個或更多較大的文件,則至少不會下載其中一個文件,因此Promise.all永遠不會觸發,因此也沒有console.log('Promise Finished:',values);

當前,它下載大多數文件(完整),但最后一個或兩個文件是部分文件。 沒有錯誤進入控制台。


var urls = ['http://www.amazons3.com/10mb.mp4',
    'http://www.amazons3.com/20mb.mp4', 'http://www.amazons3.com/15mb.mp4', 'http://www.amazons3.com/19mb.mp4', 'http://www.amazons3.com/18mb.mp4', , 'http://www.amazons3.com/20mb.mp4'];

var promises = urls.map(url => {
  return new Promise((resolve, reject) => {
    var r = request(url)
    .on('response', (resp) => {
      if (resp.statusCode === 200) {
        console.log('Started: ', url);
        r.pipe(fs.createWriteStream('files/' + fileName))

        .on('error', function(err) {
          console.log(err)
          reject(err)
        })
        .on('finish', function () {
          console.log('Downloaded: ', url);
          resolve(url);
        });
      } else {
          console.log(`${resp.statusCode} error for`, url);
          reject(`${resp.statusCode} error for ${url}`)
      }
    }).on('error', function(err) {
      console.log(err)
      reject(err)
    });
  });
});

Promise.all(promises).then(function(values){
    if (err) return console.error(err);
    console.log('Promise Finished: ', values);
});

我想知道是否有太多並發請求,這就是為什么相同的文件無法下載? 如果是這樣,我該如何解決?

我期望的結果是完全下載每個文件並啟動Promise.all,並能夠捕獲發生的任何錯誤。 此外,它必須在連接不良時表現良好。

更新:在GitHub上發現了此問題,這也許可以解釋為什么在我的場景中未觸發錯誤。 https://github.com/request/request/issues/2161

您必須相應地使用reject

var promises = urls.map(url => {
  return new Promise((resolve, reject) => {
    var r = request.get(url)
    .on('response', (resp) => {
      if (resp.statusCode === 200) {
        console.log('Started: ', url);
        r.pipe(fs.createWriteStream('files/' + url))
        .on('error', function(err) {
          console.log(err)
          reject(err)
        })
        .on('finish', function () {
          console.log('Downloaded: ', url);
          resolve(url);
        });
      } else {
          console.log(`${resp.statusCode} error for`, url);
          reject(`${resp.statusCode} error for ${url}`)
      }
    }).on('error', function(err) {
      console.log(err)
      reject(err)
    });
  });
});

如其他答案所述; 你必須拒絕。 但是,當您拒絕時,這意味着成功的所有請求都會丟失(取決於您如何繼續處理)。

您可能不希望這樣做,而是可以使用一個特殊值進行解析,以便可以弄清楚成功和失敗請求的處理方法:

function Fail(reason){this.reason=reason;};
const isFail = x=>(x&&x.constructor)===Fail;
const isNotFail = x=>!isFail(x);

var promises = urls.map(url => {
  return new Promise((resolve, reject) => {
    //same as Akash
  })
  .catch(err=>new Fail([err,url]));
});

Promise.all(promises)
.then(
  results=>{
    const successes = results.filter(isNotFail);
    const failed = results.filter(isFail);
    if(failed.length!==0){
      console.log("Some url(s) failed:");
      console.log(failed.map(([err,url])=>url));
      console.log("Errors:");
      console.log(failed.map(([err,url])=>err));
    }
  }
);

看來我正在經歷的是此錯誤的症狀: https : //github.com/request/request/issues/2161

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM