2016-12-06 3 views
1

私はpromisesアレイ内のすべての約束が解決されたときにアレイ内のすべての約束事が解決されたイベントをキャプチャするには?

Promise.all()がイベントをキャプチャされていない(SailsJSフレームワークで)NodeJSでブルーバードライブラリを使用しています。

この問題を解決するには、どのような変更を行う必要がありますか?

var Promise = require("bluebird"); 
var request = require('request'); 
var http = require('http'); 

function searchMultiple(titles) { 

    var results = []; 

    return new Promise(function(resolveGlobal, rejectGlobal){ 

    var url = "http://xxx.xxx"; 
    var promises = []; 

    titles.forEach(function (title, index) { 

     promises[index] = new Promise(function (resolve, reject) { 

     var data = {"x":title}; 

     request({ 
      uri: url, 
      method: "POST", 
      body : data 
     }, function(error, response, body) { 
      return resolve(body) 
      } 
      } 
     }, 
     function (error, response, body) { 
      console.log("error"); 
      return resolve(); 
     } 
     ); 
     }) 
    }) 

    Promise.all(promises).then(function(combinedResults) { 
     console.log("successfully resolved all promises"); 
     return resolveGlobal(combinedResults); 
    }).catch(function (reason) { 
     console.log("error"); 
     return rejectGlobal(); 
    }); 

    }) 
} 
+1

「イベントをキャプチャしない」とはどういう意味ですか? –

+0

@PankajParkar 'promises'配列のすべての約束が解決されたときに、外側の約束事(' resolveGlobal() ')を解決したいと思います。 –

+0

['Promise'コンストラクタの反パターンを避ける](http://stackoverflow.com/q/23803743/1048572)! – Bergi

答えて

0

これを試してみてください:

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

function searchMultiple(titles) { 
    return new Promise(function (resolveGlobal, rejectGlobal) { 
    var url = 'http://xxx.xxx'; 
    var promises = []; 

    titles.forEach(function (title) { 
     promises 
     .push(new Promise(function (resolve, reject) { 
      var data = { 
      'x': title 
      }; 

      request({ 
       uri: url, 
       method: 'POST', 
       body: data 
      }, 
      function (error, response, body) { 
       if (!error && response.statusCode == 200) { 
       return resolve(body); 
       } 

       return reject(error); 
      }); 
     })); 
    }); 

    Promise 
     .all(promises) 
     .then(function (combinedResults) { 
     console.log('successfully resolved all promises'); 

     return resolveGlobal(combinedResults); 
     }) 
     .catch(function (error) { 
     console.log('error'); 

     return rejectGlobal(error); 
     }); 
    }); 
} 

を、通話機能:return resolve(value)へのあなたのための必要はありませんが、

searchMultiple([...]) 
    .then(function (results) { 
    console.log(results); 
    }) 
    .catch(function (error) { 
    console.log(error); 
    }); 
+0

何を変更しましたか?なぜ?あなたの答えに説明を加えてください。 – Bergi

1

としても指定された結果値を持つべき唯一のresolve

searchMultiple関数で新しい約束事を作成する理由はありません。Promise.allが約束を返すからです。あなたはすでに持っている約束を返すべきです!

resolveGlobal()は不要です。thenは解決された値としてラップされるので、代わりにreturnの結果が得られます。

あなたのコードのすべては、あなたが代わりに未定義の値とそれを解決するのエラーハンドラでの約束を拒否検討すべき2つの非常に単純な関数

function searchMultiple(titles) { 
    //Empty array of promises 
    var promises = []; 

    var url = "http://xxx.xxx"; 

    //Get a promise for each title and push to array 
    titles.forEach(function(title){ 
    promises.push(getData(title, url)); 
    }); 

    //Wait for all promises to resolve, and return the result 
    return Promise.all(promises) 
    .then(function(arrayOfResults){ 
     //If this only shall return the array, this can be omitted aswell as the catch! 
     return arrayOfresults; 
    }) 
    .catch(function(reason){ 
     //Handle errors 
    }); 
} 

function getData(title, url){ 
    return new Promise(function(resolve, reject){ 
    var data = {"x":title}; 
     request({ 
      uri: url, 
      method: "POST", 
      body : data 
     }, function(error, response, body) { 
      resolve(body) 
      } 
      } 
     }, 
     function (error, response, body) { 
      console.log("error"); 
      //Consider rejecting here instead since you'll get a result that is 'undefined' 
      resolve(); 
     }); 
    }); 
} 

ように書き換えることができます。 undefinedの値を持つ結果配列を戻すと、さらにエラーが発生する可能性があります。

+0

'getData'関数のパラメータとして' url'と 'title'を忘れました – Bergi

+1

' .then(function(arrayOfResults){return arrayOfresults;}) 'は無意味なので、配列を何もしない場合は省略してください。 – Bergi

+1

ありがとう、それを逃した! 'Promises.all(..)'の '.then(..)'については、コンソールの出力を省略しましたが、おそらく '.then(..) ) '。 –

関連する問題