所以我想通过尝试使用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/