javascript - Promises 和 Nodejs 的具体示例(无解决方案)

标签 javascript node.js promise bluebird

所以我想通过尝试使用nodejs实现一个常见的用例来了解更多关于Promise的信息(我任意选择了Bluebird,尽管有“简洁”的文档):

我的文件中有一堆大约 9000 个 URL,还有一些空行。我愿意:

  • 过滤掉空行(url.length <= 0)
  • 过滤掉那些不再响应的内容(通过使用 request 模块的 HEAD 请求)
  • 通过 dns.resolve() 获取 IPv4 地址的 MAP
  • MAP 使用该 IPv4 地址和 http://ipinfo.io/xx.xx.xx.xx/geo获取地理数据(好吧,是的,有每日 API 限制,但我们假设我可以)
  • 将结果信息作为 JSON 对象数组写入新文件中
  • 当然,受益于这样一个事实:这将并行运行,因此比顺序执行要快得多

第一个过滤器很简单,因为它立即返回(此处使用 Bluebird):

Promise.each(urls, function(value, index, length) {
  return value.length > 0;
}).then(
  console.log(urls);
);

但是如何将异步head请求的结果反馈给Promise呢?这是另一个更完整的示例,说明我遇到了困难(请参阅内联评论):

<pre class="prettyprint lang-js">

var Promise = require('bluebird'),
  request = Promise.promisifyAll(require('request'));

var urls = ["", "https://google.com/", "http://www.nonexistent.url"];

var checkLength = function(url) {
    return Promise.resolve(url.length > 0);
}

var checkHead = function(url) {
    return Promise.resolve(
      // ??? seee below for an 'unPromised' function that works on its own
    )
}

var logit = function(value) {
  console.log((urls.length - value.length) + " empty line(s)");
}

Promise
  .filter(urls, checkLength)
  // and here? .filter(urls, checkHead) ? I don't think this would work.
  // and I haven't even look at the map functions yet, although I guess
  // that once I've understood the basic filter, map should be similar.
  .then(logit);

</pre>

对于 checkHead 函数,我计划修改如下内容:

var isURLvalid = function(url) {
  request
    .head(url)
    .on('response', function(response) {
      console.log("GOT SUCCESS: " + response);
      callback(response.statusCode < 300);
    })
    .on('error', function(error) {
      console.log("GOT ERROR: " + response);
      callback(false);
    })
};

不想提示,我仍然在拼命寻找一些好的教程介绍 Material ,这些 Material 可以帮助不熟悉 Promises 的开发人员,并展示常见用例的实际实现,就像菜谱一样。如果有的话,我很乐意得到一些指点。

最佳答案

过滤器和映射函数的工作方式与 JavaScript 数组的默认函数类似。

我之前使用过带 promise 的请求,并且有一个专门用于此目的的特定模块,称为请求 promise 。可能会更方便。

我确实觉得 request-promise 模块非常适合展示 Promise 的伟大之处。

与其陷入回调 hell ,每个添加的请求都会变得更深,你可以用 promise 来代替它

rp(login)
.then(function(body) {
    return rp(profile);
})
.then(function(body) {
    return rp(profile_settings);
})
.then(function(body) {
    return rp(logout);
})
.catch(function(err) {
    // the procedure failed
    console.error(err);
});

我将您当前的代码重写为此

var Promise = require("bluebird");
var rp = require("request-promise");

var urls = ["", "https://google.com/", "http://www.nonexistent.url"];

Promise
    // checkLength
    .filter(urls, function(url){return url.length > 0})
    .then(function(list) {
        // logit
        console.log((urls.length - list.length) + " empty line(s)");

        // checkHead
        return Promise.filter(list, function(url) {
            // using request-promise and getting full response
            return rp.head({ uri: url, resolveWithFullResponse: true })
                .promise().then(function(response) {
                    // only statusCode 200 is ok
                    return response.statusCode === 200;
                })
                .catch(function(){
                    // all other statuscodes incl. the
                    // errorcodes are considered invalid
                    return false;
                });
        })
    })
    .then(console.log);

关于javascript - Promises 和 Nodejs 的具体示例(无解决方案),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34623175/

相关文章:

node.js - Swagger 版本错误

javascript - 等到来自 mongoDB 查询的所有项目都被处理后再继续

javascript - AngularJS:搜索从服务中的 promise 返回的数组

javascript - 服务器端未收到 Extjs 5.0 模型 POST 值(工作 Extjs 4.2)

javascript - 如何查看 Handlebars 模板中的所有可用变量

javascript - 在 browserify 中将 window 传递给这个

javascript - 使用 firebase 获取给定键数组的多个单独值

Javascript 比较从提示返回的字符串

javascript - 使用 momentjs,在本地与在 Azure 上获得不同的结果

javascript - 带有异步例程的新对象