javascript - 如何在 Node/JavaScript 中重写 Promise

标签 javascript node.js

在另一个问题中 - 请参阅下面的 [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 ]

有人可以解释一下为什么这是未定义的吗?

<小时/>

[1] Iterate over async function

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

最佳答案

您需要添加一个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/

相关文章:

JavaScript:在 div.container < window.height 时做一些事情

php - 选择一组选项取决于您之前选择的选项

javascript - 如何从 greasemonkey 脚本关闭 firefox 选项卡?

javascript - Jquery- Form 第一次没有得到我的输入值

javascript - JavaScript 中字符串的长度

javascript - 在 Angular 中更新表行数据

node.js - 同一路由上的多个路由器

node.js - 使用 mongoose 版本(4.11.0)连接到 Mongo DB

node.js 使用临时/etc/hosts 设置发送 http 请求

node.js - 为 RTBkit 使用 node.js 的投标代理