在另一个问题中 - 请参阅下面的 [1] - 我询问如何迭代列表并为该列表中的每个元素调用异步函数,最后使用累积的结果列表。
用户 tresdin [2] 非常友善地指出了 Node 中的 Promises。
他的例子正是我正在寻找的。又来了:
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' ] ]
现在我的问题是:我可以将迭代之外的“return new Promise”部分移到像这样的新函数中吗?
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
这将产生完全不同的结果:
$ node promises_example_2.js
[ undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined ]
有人可以解释一下为什么这是未定义的吗?
<小时/>最佳答案
您需要添加一个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
方法。
关于javascript - 如何在 Node/JavaScript 中重写 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36422758/