質問編集履歴

4 promise初心者であることを追記

TEA

TEA score 64

2016/06/14 10:07  投稿

(Promise)直列処理の中でreduceを扱う事はできますか?
promiseの記述方法が正しいか分からなかったのでご質問させてください。環境はnode.js v4.3です。
promise初心者です。promiseの記述方法がこれで正しいか分からなかったのでご質問させてください。環境はnode.js v4.3です。
promiseの直列処理のいくつかの処理の中で、配列要素を処理するreduceを追加することはできますか?また、2つ目の質問ですが、下記コード中の`function taskB_Work(value)`で記述する処理によっては、逐次処理が最後まで進むものの、プロセスが終了しない事がありました。これはどのような原因が考えられますでしょうか?(`console.log("complete!");`以下を参照)
主にこのような処理を逐次処理で行いたいと考えております。
1. 配列を取得
2. 配列要素を元に処理 (配列要素の数だけ逐次処理したい)
3. 処理した結果を出力
現在、以下のようなコードを書いていますが、このような形でpromiseの記述は問題ないでしょうか?
> 参考記事: Qiita | Promiseについて0から勉強してみた
> [http://qiita.com/toshihirock/items/e49b66f8685a8510bd76](http://qiita.com/toshihirock/items/e49b66f8685a8510bd76)
``` javascript
// 配列の取得を行うタスク
function taskA() {
 return new Promise(function(resolve, reject) {
     var Arr = ["a","b","c","d","e"];
       resolve(Arr);
   });
}
// taskAで取得した値を加工するタスク
function taskB(arr) {
 var editedArr = [];
 return new Promise(function(resolve, reject) {
   return arr.reduce(function(promise, value) {
         return promise.then(function() {
             return taskB_Work(value);
         }).then(function(editedElement){
       editedArr.push(editedElement);
     });
     }, Promise.resolve() )
     .then(
         function(){
             resolve(editedArr);
         },
         function(){
             reject("taskB 処理に失敗");
         }
     );
 });
}
// taskBのreduceで呼び出され、配列要素に対して行う処理
function taskB_Work(value){
   return new Promise(function(resolve, reject) {
       setTimeout(function () {
             console.log("[taskB_Work] value="+value);
             resolve(value + "_edited");
       }, 2000);
   });
}
// taskBで加工した配列の値を出力するタスク
function taskC(editedArr) {
 return new Promise(function(resolve, reject) {
     console.log("[taskC]:");
     console.log(editedArr);
   resolve();
 });
}
//逐次処理を行う
function sequenceTasks(tasks) {
   function recordValue(results, value) {
       return value;
   }
   var pushValue = recordValue.bind(null, []);
   return tasks.reduce(function (promise, task) {
       return promise.then(task).then(pushValue);
   }, Promise.resolve());
}
var promises = {
 doTaskA: function() {
   return taskA().then();
 },
 doTaskB: function(arr) {
   return taskB(arr).then();
 },
 doTaskC: function(editedArr) {
   return taskC(editedArr).then();
 }
};
function main() {
return sequenceTasks([ promises.doTaskA, promises.doTaskB, promises.doTaskC ]);
}
main().then(function(value) {
 console.log("complete!");
 //function taskB_Work(value)`で記述する処理によっては、逐次処理がここまで進むものの、プロセスが終了しない事があります。
}).catch(function(error) {
 console.log("error:" + error);
});
```
taskB_Workの処理内容は実際には以下のようなものを考えています。改行区切りのURLが保存されているテキストファイルを開き(taskA)、taskBを実行後に、新たに取得したURLをテキストファイルで出力する(taskC)という処理です。
taskB_Workの処理内容は実際には以下のようなものを考えています。全体の処理の概要は、
- taskA : 改行区切りのURLが保存されているテキストファイルを開き、URLを配列要素に格納
- taskB : 各配列要素のURLに対して、flickrapiを実行
- taskC : 新たに取得したURLをテキストファイルで出力
という流れです。
``` javascript
// flickrのリサイズ画像URL(inPhotoURL)を元に、オリジナルサイズの画像URLを取得する。
/*
   var FlickrAPI = require("flickrapi");
   var flickrApiOptions = {
               api_key           : process.env.api_key,
               secret            : process.env.secret,
               permissions       : process.env.permissions,
               user_id           : process.env.user_id,
               access_token      : process.env.access_token,
               access_token_secret: process.env.access_token_secret
           };
*/
function taskB_Work(inPhotoURL){
   return new Promise(function(resolve, reject) {
       FlickrAPI.authenticate(flickrApiOptions, function(error, flickr) {
           
           var matchPat = inPhotoURL.match(/(https:\/\/farm[0-9]\.staticflickr\.com\/[0-9]+\/)([0-9]+)_([0-9a-z]+)[0-9a-z_]*\.jpg/);
           
           var parameter = {
               "api_key" : flickrApiOptions.api_key ,
               "photo_id" : matchPat[2],
               "secret" : matchPat[3]
           };
           
           if(!error){
               // getInfoにより、originalsecretとoriginalformatを取得
               // (getInfo) https://www.flickr.com/services/api/flickr.photos.getInfo.html
               flickr.photos.getInfo(parameter, function(err, result) {
                   if(err) {
                         reject("flickr APIの実行に失敗しました : " + err);
                   }else{
                       resolve(matchPat[1] + matchPat[2] + "_"+ result.photo.originalsecret +"_o."+ result.photo.originalformat);
                   }
               });
           }else{
               reject("flickr APIの認証に失敗しました :" + error);
           }
       });
       
   });
}
```
  • JavaScript

    22249 questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Node.js

    2546 questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

3 taskB_Workの具体的内容を追記しました

TEA

TEA score 64

2016/06/14 09:48  投稿

(Promise)直列処理の中でreduceを扱う事はできますか?
promiseの記述方法が正しいか分からなかったのでご質問させてください。環境はnode.js v4.3です。
promiseの直列処理のいくつかの処理の中で、配列要素を処理するreduceを追加することはできますか?また、2つ目の質問ですが、下記コード中の`function taskB_Work(value)`で記述する処理によっては、逐次処理が最後まで進むものの、プロセスが終了しない事がありました。これはどのような原因が考えられますでしょうか?(`console.log("complete!");`以下を参照)
主にこのような処理を逐次処理で行いたいと考えております。
1. 配列を取得
2. 配列要素を元に処理 (配列要素の数だけ逐次処理したい)
3. 処理した結果を出力
現在、以下のようなコードを書いていますが、このような形でpromiseの記述は問題ないでしょうか?
> 参考記事: Qiita | Promiseについて0から勉強してみた
> [http://qiita.com/toshihirock/items/e49b66f8685a8510bd76](http://qiita.com/toshihirock/items/e49b66f8685a8510bd76)
``` javascript
// 配列の取得を行うタスク
function taskA() {
 return new Promise(function(resolve, reject) {
     var Arr = ["a","b","c","d","e"];
       resolve(Arr);
   });
}
// taskAで取得した値を加工するタスク
function taskB(arr) {
 var editedArr = [];
 return new Promise(function(resolve, reject) {
   return arr.reduce(function(promise, value) {
         return promise.then(function() {
             return taskB_Work(value);
         }).then(function(editedElement){
       editedArr.push(editedElement);
     });
     }, Promise.resolve() )
     .then(
         function(){
             resolve(editedArr);
         },
         function(){
             reject("taskB 処理に失敗");
         }
     );
 });
}
// taskBのreduceで呼び出され、配列要素に対して行う処理
function taskB_Work(value){
   return new Promise(function(resolve, reject) {
       setTimeout(function () {
             console.log("[taskB_Work] value="+value);
             resolve(value + "_edited");
       }, 2000);
   });
}
// taskBで加工した配列の値を出力するタスク
function taskC(editedArr) {
 return new Promise(function(resolve, reject) {
     console.log("[taskC]:");
     console.log(editedArr);
   resolve();
 });
}
//逐次処理を行う
function sequenceTasks(tasks) {
   function recordValue(results, value) {
       return value;
   }
   var pushValue = recordValue.bind(null, []);
   return tasks.reduce(function (promise, task) {
       return promise.then(task).then(pushValue);
   }, Promise.resolve());
}
var promises = {
 doTaskA: function() {
   return taskA().then();
 },
 doTaskB: function(arr) {
   return taskB(arr).then();
 },
 doTaskC: function(editedArr) {
   return taskC(editedArr).then();
 }
};
function main() {
return sequenceTasks([ promises.doTaskA, promises.doTaskB, promises.doTaskC ]);
}
main().then(function(value) {
 console.log("complete!");
 //function taskB_Work(value)`で記述する処理によっては、逐次処理がここまで進むものの、プロセスが終了しない事があります。
}).catch(function(error) {
 console.log("error:" + error);
});
```  
 
taskB_Workの処理内容は実際には以下のようなものを考えています。改行区切りのURLが保存されているテキストファイルを開き(taskA)、taskBを実行後に、新たに取得したURLをテキストファイルで出力する(taskC)という処理です。  
 
``` javascript  
 
// flickrのリサイズ画像URL(inPhotoURL)を元に、オリジナルサイズの画像URLを取得する。  
/*  
   var FlickrAPI = require("flickrapi");  
   var flickrApiOptions = {  
               api_key           : process.env.api_key,  
               secret            : process.env.secret,  
               permissions       : process.env.permissions,  
               user_id           : process.env.user_id,  
               access_token      : process.env.access_token,  
               access_token_secret: process.env.access_token_secret  
           };  
*/  
function taskB_Work(inPhotoURL){  
   return new Promise(function(resolve, reject) {  
       FlickrAPI.authenticate(flickrApiOptions, function(error, flickr) {  
             
           var matchPat = inPhotoURL.match(/(https:\/\/farm[0-9]\.staticflickr\.com\/[0-9]+\/)([0-9]+)_([0-9a-z]+)[0-9a-z_]*\.jpg/);  
             
           var parameter = {  
               "api_key" : flickrApiOptions.api_key ,  
               "photo_id" : matchPat[2],  
               "secret" : matchPat[3]  
           };  
             
           if(!error){  
               // getInfoにより、originalsecretとoriginalformatを取得  
               // (getInfo) https://www.flickr.com/services/api/flickr.photos.getInfo.html  
               flickr.photos.getInfo(parameter, function(err, result) {  
                   if(err) {  
                         reject("flickr APIの実行に失敗しました : " + err);  
                   }else{  
                       resolve(matchPat[1] + matchPat[2] + "_"+ result.photo.originalsecret +"_o."+ result.photo.originalformat);  
                   }  
               });  
           }else{  
               reject("flickr APIの認証に失敗しました :" + error);  
           }  
       });  
         
   });  
}  
 
```
  • JavaScript

    22249 questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Node.js

    2546 questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

2 コードについて、関数内部で変数を定義するよう変更しました

TEA

TEA score 64

2016/06/13 17:00  投稿

(Promise)直列処理の中でreduceを扱う事はできますか?
promiseの記述方法が正しいか分からなかったのでご質問させてください。環境はnode.js v4.3です。
promiseの直列処理のいくつかの処理の中で、配列要素を処理するreduceを追加することはできますか?また、2つ目の質問ですが、下記コード中の`function taskB_Work(value)`で記述する処理によっては、逐次処理が最後まで進むものの、プロセスが終了しない事がありました。これはどのような原因が考えられますでしょうか?(`console.log("complete!");`以下を参照)
主にこのような処理を逐次処理で行いたいと考えております。
1. 配列を取得
2. 配列要素を元に処理 (配列要素の数だけ逐次処理したい)
3. 処理した結果を出力
現在、以下のようなコードを書いていますが、このような形でpromiseの記述は問題ないでしょうか?
> 参考記事: Qiita | Promiseについて0から勉強してみた
> [http://qiita.com/toshihirock/items/e49b66f8685a8510bd76](http://qiita.com/toshihirock/items/e49b66f8685a8510bd76)
``` javascript
var Arr, Arr_edited;  
Arr       = [];  
Arr_edited = [];  
// 配列の取得を行うタスク
function taskA() {
     return new Promise(function(resolve, reject) {
         Arr = ["a","b","c","d","e"];
       resolve();
 return new Promise(function(resolve, reject) {
     var Arr = ["a","b","c","d","e"];
       resolve(Arr);
   });
}
// taskAで取得した値を加工するタスク
function taskB() {
function taskB(arr) {
 var editedArr = [];
 return new Promise(function(resolve, reject) {
   return Arr.reduce(function(promise, value) {
       return promise.then(function() {
           return taskB_Work(value);
       });
   }, Promise.resolve())
   .then(
       function(){
           resolve();
       },
       function(){
           reject("taskB 処理に失敗");
       }
   );
   return arr.reduce(function(promise, value) {
         return promise.then(function() {
             return taskB_Work(value);
         }).then(function(editedElement){
       editedArr.push(editedElement);
     });
     }, Promise.resolve() )
     .then(
         function(){
             resolve(editedArr);
         },
         function(){
             reject("taskB 処理に失敗");
         }
     );
 });
}
 
// taskBのreduceで呼び出され、配列要素に対して行う処理
function taskB_Work(value){
   return new Promise(function(resolve, reject) {
       setTimeout(function () {
             console.log("[taskB_Work] value="+value);
             Arr_edited.push(value + "_edited");
             resolve();
             resolve(value + "_edited");
       }, 2000);
         
   });
}
// taskBで加工した配列の値を出力するタスク
function taskC() {
function taskC(editedArr) {
 return new Promise(function(resolve, reject) {
     console.log("[taskC]:");
     console.log(Arr_edited);
     console.log(editedArr);
   resolve();
 });
}
 
 
//逐次処理を行う
function sequenceTasks(tasks) {
   function recordValue(results, value) {
       results.push(value);
       return results;
       return value;
   }
   var pushValue = recordValue.bind(null, []);
   return tasks.reduce(function (promise, task) {
       return promise.then(task).then(pushValue);
   }, Promise.resolve());
}
var promises = {
 doTaskA: function() {
   return taskA().then();
 },
 doTaskB: function() {
   return taskB().then();
 doTaskB: function(arr) {
   return taskB(arr).then();
 },
 doTaskC: function() {
   return taskC().then();
 doTaskC: function(editedArr) {
   return taskC(editedArr).then();
 }
};
function main() {
return sequenceTasks([ promises.doTaskA, promises.doTaskB, promises.doTaskC ]);
}
 
main().then(function(value) {
 console.log("complete!");
 //function taskB_Work(value)に記述する処理内容によっては、逐次処理がここまで進むものの、プロセスが終了しない事がありました。
 //function taskB_Work(value)`で記述する処理によっては、逐次処理がここまで進むものの、プロセスが終了しない事があります。
}).catch(function(error) {
 console.log("error:" + error);
});
```
  • JavaScript

    22249 questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Node.js

    2546 questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

1 引用の追加,誤字修正

TEA

TEA score 64

2016/06/10 17:45  投稿

(Promise)直列処理の中でreduceを扱う事はできますか?
promiseの記述方法が正しいか分からなかったのでご質問させてください。環境はnode.js v4.3です。
promiseの直列処理のいくつかの処理の中で、配列要素を処理するreduceを追加することはできますか?また、2つ目の質問ですが、下記コード中の`function taskB_Work(value)`で記述する処理によっては、逐次処理が最後まで進むものの、プロセスが終了しない事がありました。これはどのような原因が考えられますでしょうか?(`console.log("complete!");`以下を参照)
主にこのような処理を逐次処理で行いたいと考えております。
1. 配列を取得
2. 配列要素を元に処理 (配列要素の数だけ逐次処理したい)
3. 処理した結果を出力
現在、以下のようなコードを書いていますが、このような形でpromiseの記述は問題ないでしょうか?
 
> 参考記事: Qiita | Promiseについて0から勉強してみた  
> [http://qiita.com/toshihirock/items/e49b66f8685a8510bd76](http://qiita.com/toshihirock/items/e49b66f8685a8510bd76)  
``` javascript
var Arr, Arr_edited;
Arr       = [];
Arr_edited = [];
// 配列の取得を行うタスク
function taskA() {
     return new Promise(function(resolve, reject) {
         Arr = ["a","b","c","d","e"];
       resolve();
   });
}
// taskAで取得した値を加工するタスク
function taskB() {
 return new Promise(function(resolve, reject) {
   return Arr.reduce(function(promise, value) {
       return promise.then(function() {
           return taskB_Work(value);
       });
   }, Promise.resolve())
   .then(
       function(){
           resolve();
       },
       function(){
           reject("taskB 処理に失敗");
       }
   );
 });
}
// taskBのreduceで呼び出され、配列要素に対して行う処理
function taskB_Work(value){
   return new Promise(function(resolve, reject) {
       setTimeout(function () {
             console.log("[taskB_Work] value="+value);
             Arr_edited.push(value + "_edited");
             resolve();
       }, 2000);
       
   });
}
// taskBで加工した配列の値を出力するタスク
function taskC() {
 return new Promise(function(resolve, reject) {
     console.log("[taskC]:");
     console.log(Arr_edited);
   resolve();
 });
}
//逐次処理を行う
function sequenceTasks(tasks) {
   function recordValue(results, value) {
       results.push(value);
       return results;
   }
   var pushValue = recordValue.bind(null, []);
   return tasks.reduce(function (promise, task) {
       return promise.then(task).then(pushValue);
   }, Promise.resolve());
}
var promises = {
 doTaskA: function() {
   return taskA().then();
 },
 doTaskB: function() {
   return taskB().then();
 },
 doTaskC: function() {
   return taskC().then();
 }
};
function main() {
return sequenceTasks([ promises.doTaskA, promises.doTaskB, promises.doTaskC ]);
}
main().then(function(value) {
 console.log("complete!");
 //function taskB_Work(value)`で記述する処理によっては、逐次処理がここまで進むものの、プロセスが終了しない事があります。
 //function taskB_Work(value)に記述する処理内容によっては、逐次処理がここまで進むものの、プロセスが終了しない事がありました。
}).catch(function(error) {
 console.log("error:" + error);
});
```
  • JavaScript

    22249 questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Node.js

    2546 questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る