2016-04-16 28 views
1

私はnode.jsの一括ダウンローダを作成しており、ブルーバードの約束を理解しようとしています。 並列要求とディスク書き込みの回数を制限します。 私が理解しているように、Promise.map(){concurrent: }としたいと思います。Node.jsの一括ダウンロードとBluebirdの約束

pipe()http.get()は自動的にお約束できないため、私はカスタム約束を使用しようとしています。

しかし、私はthen()メカニズムを完全に理解していません。 私には、返品された約束は、チェーン全体が履行されたときにのみ満たされるように思えます。

しかし、私のコードでは、チェーン内の最初の約束事はmap()によって待たれているように見え、多くの要求とディスクの書き込みは並行して行われます。

import Promise from 'bluebird'; 
import fs from 'fs'; 
import https from 'https'; 

Promise.promisifyAll(fs); 
Promise.map(Images, image => { 
     console.log("Opening image " + image.id); 
     let file = fs.createWriteStream(dir + '/' + image.id + '.jpg'); 
     return new Promise((resolve, reject) => { 
       console.log("Downloading image " + image.id); 
       https.get(image.url, resolve).on("error", reject); 
      }) 
      .then(response => { 
       response.pipe(file); 
       console.log("Saving image " + image.id); 
       return new Promise((resolve, reject) => { 
        file.on("finish", resolve); 
        file.on("error", reject); 
       }); 
      }) 
      .then(() => { 
       console.log("Finished writing image " + image.id); 
       file.close(); 
      }) 
      .catch(e => { 
       console.log("Error during image save of " + image.id + ": " + e.code) 
      }); 
    }, {concurrent: 50}) 
     .then(res => { 
      console.log("Finished writing all images") 
     }) 
     .catch(e => { 
      console.log("Some images failed to be written: " + e.code) 
     }); 
} 

私は間違っていますか?約束の履行と拒絶の流れを理解するのを助けてくれますか?

+0

を考え出すことができる最短の作業例です。あなたは、50以上のダウンロード+ディスクライタが同時に発生していると言っていますか?あなたは結果のログを投稿できますか(縮尺の例では、並行処理5の10個のファイル)、お願いしますか? – Bergi

+1

私はそれを理解しました。キーワードは 'concurrent'ではなく' concurrency'です。失敗 –

答えて

3

私が理解できるところから、あなたは約束を持って複数の画像をダウンロードしようとしています。実際にfsを約束する必要はありません。あなたは簡単にダウンロードするためにrequestモジュールを使用する必要があります。ここで

は、私はあなたのコードが正しいように見える

var Promise = require('bluebird'); 
var path = require('path'); 
var fs = require('fs'); 
var request = require('request'); 

var images = [{ 
    url: 'http://bluebirdjs.com/img/logo.png', 
    file_name: 'bluebird.png' 
}, { 
    url: 'http://design.ubuntu.com/wp-content/uploads/ubuntu-logo32.png', 
    file_name: 'ubuntu.png' 
}, { 
    url: 'https://www.raspberrypi.org/wp-content/uploads/2012/03/raspberry-pi-logo.png', 
    file_name: 'raspberry-pi.png' 
}]; 

// To Download Serially 
Promise.each(images, image => new Promise((resolve, reject) => { 
    console.log('Downloading Image: ' + image.file_name); 
    request(image.url).on('error', reject).pipe(fs.createWriteStream(path.join(__dirname, image.file_name))).on('finish',() => { 
     console.log('Downloaded Image: ' + image.file_name); 
     resolve(); 
    }); 
})).then(() => { 
    console.log('All Image Downloaded!'); 
}).catch(err => { 
    console.error('Failed: ' + err.message); 
}); 

// To Download in Parallel (with 2 maximum concurrent jobs) 
Promise.map(images, image => new Promise((resolve, reject) => { 
    console.log('Downloading Image: ' + image.file_name); 
    request(image.url).on('error', reject).pipe(fs.createWriteStream(path.join(__dirname, image.file_name))).on('finish',() => { 
     console.log('Downloaded Image: ' + image.file_name); 
     resolve(); 
    }); 
}), { 
    concurrency: 2 
}).then(() => { 
    console.log('All Image Downloaded!'); 
}).catch(err => { 
    console.error('Failed: ' + err.message); 
}); 
+0

ありがとうございます。あなたの実装は確かにきれいです。私は間違いを理解した。私は 'Promise.map()'のオプションオブジェクトで正しいプロパティを使用していませんでした –

+0

ところで、私はここには含まれていないコードの別の部分について 'fs'を約束していました。 –

関連する問題