promise初心者です。promiseの記述方法がこれで正しいか分からなかったのでご質問させてください。環境はnode.js v4.3です。
promiseの直列処理のいくつかの処理の中で、配列要素を処理するreduceを追加することはできますか?また、2つ目の質問ですが、下記コード中のfunction taskB_Work(value)
で記述する処理によっては、逐次処理が最後まで進むものの、プロセスが終了しない事がありました。これはどのような原因が考えられますでしょうか?(console.log("complete!");
以下を参照)
主にこのような処理を逐次処理で行いたいと考えております。
- 配列を取得
- 配列要素を元に処理 (配列要素の数だけ逐次処理したい)
- 処理した結果を出力
現在、以下のようなコードを書いていますが、このような形でpromiseの記述は問題ないでしょうか?
参考記事: Qiita | Promiseについて0から勉強してみた
http://qiita.com/toshihirock/items/e49b66f8685a8510bd76
javascript
1 2// 配列の取得を行うタスク 3function taskA() { 4 return new Promise(function(resolve, reject) { 5 var Arr = ["a","b","c","d","e"]; 6 resolve(Arr); 7 }); 8} 9 10// taskAで取得した値を加工するタスク 11function taskB(arr) { 12 var editedArr = []; 13 return new Promise(function(resolve, reject) { 14 return arr.reduce(function(promise, value) { 15 return promise.then(function() { 16 return taskB_Work(value); 17 }).then(function(editedElement){ 18 editedArr.push(editedElement); 19 }); 20 }, Promise.resolve() ) 21 .then( 22 function(){ 23 resolve(editedArr); 24 }, 25 function(){ 26 reject("taskB 処理に失敗"); 27 } 28 ); 29 }); 30} 31 32 33// taskBのreduceで呼び出され、配列要素に対して行う処理 34function taskB_Work(value){ 35 return new Promise(function(resolve, reject) { 36 setTimeout(function () { 37 console.log("[taskB_Work] value="+value); 38 resolve(value + "_edited"); 39 }, 2000); 40 }); 41} 42 43// taskBで加工した配列の値を出力するタスク 44function taskC(editedArr) { 45 return new Promise(function(resolve, reject) { 46 console.log("[taskC]:"); 47 console.log(editedArr); 48 resolve(); 49 }); 50} 51 52 53 54//逐次処理を行う 55function sequenceTasks(tasks) { 56 function recordValue(results, value) { 57 return value; 58 } 59 var pushValue = recordValue.bind(null, []); 60 return tasks.reduce(function (promise, task) { 61 return promise.then(task).then(pushValue); 62 }, Promise.resolve()); 63} 64 65var promises = { 66 doTaskA: function() { 67 return taskA().then(); 68 }, 69 doTaskB: function(arr) { 70 return taskB(arr).then(); 71 }, 72 doTaskC: function(editedArr) { 73 return taskC(editedArr).then(); 74 } 75}; 76 77function main() { 78 return sequenceTasks([ promises.doTaskA, promises.doTaskB, promises.doTaskC ]); 79} 80 81 82main().then(function(value) { 83 console.log("complete!"); 84 //function taskB_Work(value)`で記述する処理によっては、逐次処理がここまで進むものの、プロセスが終了しない事があります。 85}).catch(function(error) { 86 console.log("error:" + error); 87});
taskB_Workの処理内容は実際には以下のようなものを考えています。全体の処理の概要は、
- taskA : 改行区切りのURLが保存されているテキストファイルを開き、URLを配列要素に格納
- taskB : 各配列要素のURLに対して、flickrapiを実行
- taskC : 新たに取得したURLをテキストファイルで出力
という流れです。
javascript
1 2// flickrのリサイズ画像URL(inPhotoURL)を元に、オリジナルサイズの画像URLを取得する。 3/* 4 var FlickrAPI = require("flickrapi"); 5 var flickrApiOptions = { 6 api_key : process.env.api_key, 7 secret : process.env.secret, 8 permissions : process.env.permissions, 9 user_id : process.env.user_id, 10 access_token : process.env.access_token, 11 access_token_secret: process.env.access_token_secret 12 }; 13*/ 14function taskB_Work(inPhotoURL){ 15 return new Promise(function(resolve, reject) { 16 FlickrAPI.authenticate(flickrApiOptions, function(error, flickr) { 17 18 var matchPat = inPhotoURL.match(/(https:\/\/farm[0-9]\.staticflickr\.com\/[0-9]+\/)([0-9]+)_([0-9a-z]+)[0-9a-z_]*\.jpg/); 19 20 var parameter = { 21 "api_key" : flickrApiOptions.api_key , 22 "photo_id" : matchPat[2], 23 "secret" : matchPat[3] 24 }; 25 26 if(!error){ 27 // getInfoにより、originalsecretとoriginalformatを取得 28 // (getInfo) https://www.flickr.com/services/api/flickr.photos.getInfo.html 29 flickr.photos.getInfo(parameter, function(err, result) { 30 if(err) { 31 reject("flickr APIの実行に失敗しました : " + err); 32 }else{ 33 resolve(matchPat[1] + matchPat[2] + "_"+ result.photo.originalsecret +"_o."+ result.photo.originalformat); 34 } 35 }); 36 }else{ 37 reject("flickr APIの認証に失敗しました :" + error); 38 } 39 }); 40 41 }); 42} 43
回答1件
あなたの回答
tips
プレビュー