2016-04-05 14 views
0

別の質問 - 下記の[1]を参照してください - リストを反復処理し、そのリストの各要素に対して非同期関数を呼び出し、最後に累積結果リストを使用する方法を尋ねました。ノード/ JavaScriptでプロミスを書き直す方法

ユーザーtresdin [2]は、Promises in Nodeを指し示すほど親切でした。

彼の例は私が探していたものです。ここでは、再びです:

var request = require("request"), 
    cheerio = require("cheerio"), 
    base_url = "http://de.indeed.com/Jobs?q="; // after equal sign for instance: sinatra&l= 
var Promise = require('promise'); 

var search_words = ["django", "python", "flask", 
        "rails", "ruby", 
        "node", "javascript", "angularjs", "react", 
        "java", "grails", "groovy", 
        "php", "symfony", "laravel" ]; 


Promise.all(
    search_words.map(function(keyword) { // map function on each element in search_words 
     return new Promise(function(resolve, reject) { // create a Promise instance for each element in search_words 
      request(base_url + keyword + "&l=", function(err, resp, body) { 
       if (err) { 
        return reject(err); 
       } 
       $ = cheerio.load(body); 
       num = $("#searchCount")[0].children[0].data.split(" ").reverse()[0]; 
       resolve([keyword, num]); // will return value [keyword, num] 
      }); // request(... 
     }); // return new Promise(...) 
    }) // map 
) // Promise.all 
    .then(function(map_searchword) { 
     console.log(map_searchword); 
    }); // then 

それがお届けします呼び出し:

$ node promises_example.js 
[ [ 'django', '139' ], 
    [ 'python', '3.328' ], 
    [ 'flask', '14' ], 
    [ 'rails', '406' ], 
    [ 'ruby', '1.061' ], 
    [ 'node', '685' ], 
    [ 'javascript', '9.169' ], 
    [ 'angularjs', '1.164' ], 
    [ 'react', '376' ], 
    [ 'java', '19.100' ], 
    [ 'grails', '47' ], 
    [ 'groovy', '163' ], 
    [ 'php', '4.978' ], 
    [ 'symfony', '482' ], 
    [ 'laravel', '110' ] ] 

今私の質問です:私はそうのような新機能への繰り返しの外で「新しい約束を返す」の部分を移動できますか?

$ node promises_example_2.js 
[ undefined, 
    undefined, 
    undefined, 
    undefined, 
    undefined, 
    undefined, 
    undefined, 
    undefined, 
    undefined, 
    undefined, 
    undefined, 
    undefined, 
    undefined, 
    undefined, 
    undefined ] 

は、誰かがこれが定義されていない理由を説明することができます:

var request = require("request"), 
    cheerio = require("cheerio"), 
    base_url = "http://de.indeed.com/Jobs?q="; // after equal sign for instance: sinatra&l= 
var Promise = require('promise'); 

var search_words = ["django", "python", "flask", 
        "rails", "ruby", 
        "node", "javascript", "angularjs", "react", 
        "java", "grails", "groovy", 
        "php", "symfony", "laravel" ]; 


// moved "return new Promise()" out of iteration to a function 
var do_request = function(keyword) { 
    return new Promise(function(resolve, reject) { // create a Promise instance for each element in search_words 
     request(base_url + keyword + "&l=", function(err, resp, body) { 
      if (err) { 
       return reject(err); 
      } 
      $ = cheerio.load(body); 
      num = $("#searchCount")[0].children[0].data.split(" ").reverse()[0]; 
      resolve([keyword, num]); // will return value [keyword, num] 
     }); // request(... 
    }); // return new Promise(...) 
} // function 

Promise.all(
    search_words.map(function(keyword) { // map function on each element in search_words 
     do_request(keyword); 
    }) // map 
) // Promise.all 
    .then(function(map_of_resolved_promises) { 
     console.log(map_of_resolved_promises); 
    }); // then 

これは全く異なる結果をお届けしますか!


[1] Iterate over async function

を[2] https://stackoverflow.com/users/3247703/tresdin

+0

'search_words.map(do_request)'を試したことがありますか? – cl3m

+0

優秀!これは動作します! - しかし、なぜ? – Ugur

+0

マップ関数でdo_requestを返すのを忘れてしまった。これも同様に動作します: 'return do_request(keyword);' – kazenorin

答えて

1

をあなたはreturnステートメントを追加する必要があり、次のいずれか

Promise.all(
    search_words.map(function(keyword) { // map function on each element in search_words 
     return do_request(keyword); 
    }) 
) 

それとも、単に行うことができます。

Promise.all(search_words.map(do_request)) 

map関数は、その引数(ここではキーワード)を直接do_requestメソッドに渡します。

+0

ありがとうございました!// JavaScriptがSchemeプログラミング言語を思い起こさせる方法を見てみましょう – Ugur

+0

私はSchemeについてよく知らないですが、Javascriptを楽しんでうれしいです; – cl3m

0

あなたは、約束がsearch_words.mapコールバックに渡されていませんdo_requestから返さ番目の最初の例では

search_words.map(do_request) 

または

search_words.map(function(keyword) { 
    return do_request(keyword); 
}) 

search_words.map(function(keyword) { 
    do_request(keyword); 
}) 

を交換する必要があります。その結果、代わりにundefinedが返されます。そのため、undefined値の配列が得られます。

2番目の例は元のコードと同等ですが、最後のコードは各繰り返しで余分なコールバックが必要です。したがって、より多くのメモリが必要です。つまり、ループ内で他のものを実行する必要がある場合にのみ、最後のソリューションを使用する必要があります。例:

search_words.map(function(keyword) { 
    return do_request(keyword + 'something'); 
}) 
+0

ありがとう!この答えを受け入れるだろうか(それは非常に良い説明なので)、user @ cl3mはもっと速かった。ありがとう! – Ugur

関連する問題