LoginSignup
2
1

More than 5 years have passed since last update.

Promiseを順次(直列)実行するサンプル

Last updated at Posted at 2016-09-15

よく忘れるので(まぁググればけっこう出てくるのでメモの必要もそれほど感じなくなってきたけど)メモしておく。※よくよく見るとQiitaにも同じような記事結構ある。。。
Array要素を非同期な処理でPromiseを使って順次実行する場合、reduceを使うと便利という話。

下記のようなサンプルでいかがでしょうか。

var datas= [
    {timeout:10, message:'Hello'},
    {timeout:100, message:'Promise'},
    {timeout:5000, message:'World'},
    {timeout:100, message:'!!!'}
];

function sequentialExec(arr){
    return arr.reduce(function(prev,current,index,array){
        return prev.then(function(prevResult){
            return new Promise(function(resolve,reject){
                if(current && typeof current.timeout === 'number' && typeof current.message === 'string'){
                    setTimeout(function(){
                        console.log('Prev:%s, Current:%s',prevResult,current.message);
                        resolve(current.message);
                    },current.timeout);
                }else{
                    reject(new Error('invalid data.'));
                }
            });
        });
    },Promise.resolve());
}

sequentialExec(datas).then(function(lastResult){
    console.log('Process completed: %s', lastResult);
}).catch(function(e){
    console.log('Process error: %s', e.message);
});

ということはこんな感じの作っておけば便利だったりするのかな?

Promise.reduce = function(arr,func){
    return arr.reduce(function(prev,current){
        return prev.then(function(result){
            return new Promise(function(resolve, reject){
                func(resolve,reject,result,current);
            });
        });
    },Promise.resolve());
};

これを使うと、最初に書いたコードは

var datas= [
    {timeout:10,message:'Hello'},
    {timeout:100,message:'Promise'},
    {timeout:5000,message:'World'},
    {timeout:100, message:'!!!'}
];

function proc(resolve,reject,prevResult,current){
    if(current && typeof current.timeout === 'number' && typeof current.message === 'string'){
        setTimeout(function(){
            console.log('Prev:%s,Current:%s',prevResult,current.message);
            resolve(current.message);
        },current.timeout);
    }else{
        reject(new Error('invalid data.'));
    }
};

Promise.reduce(datas,proc).then(function(lastResult){
    console.log('Process completed: %s', lastResult);
}).catch(function(e){
    console.log('Process error: %s', e.message);
});

とかなるのかな。まぁ一応やりたいことに集中できるかなぁ。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1