NodeJS 6.9.3
我写了一个简单的NodeJS应用程序,它发出如下所示的请求:
var http_request = require('request')
http_request(
{ method: 'GET'
, uri: 'https://search-xxxxxx.us-east-1.es.amazonaws.com/facts/_search?pretty=true'
, 'content-type': 'application/json'
, body: es_regexp_query_as_string
}
, function (error, response, body) {
if(
response.statusCode == 201
||
response.statusCode == 200) {
它很棒。我在回调中做任何我需要做的事情。但是,现在我需要重新构建此应用程序,以便它可以执行任意数量的请求,而不是执行一个HTTP请求。据我了解,在NodeJS中处理这个问题的理想“设计模式”是将每个请求包装在Promise中,然后将所有Promise交给调用:
Promise.all(something)
但我一直在阅读,我无法找到如何将HTTP请求转换为Promises。或者更确切地说,存在大量相互矛盾的建议。显然,在过去的一两年里,NodeJS中的“Promise”概念发生了很大变化。
我试图简单地将整个代码块包装在Promise中,但这不起作用。那我该怎么办?
答案 0 :(得分:2)
我建议您使用已经解决了问题的请求承诺(https://github.com/request/request-promise)。
答案 1 :(得分:0)
您可以考虑使用request-promise
替代node-fetch
,而不是make
。这个软件包实现了Fetch API,这可能是在服务器和客户端上执行HTTP请求的未来,它100%承担承诺,并且它比该请求库稍微麻烦。
答案 2 :(得分:0)
如果您想要不带任何外部模块的解决方案,请检查以下代码:
// Dependencies
var http = require('http');
var https = require('https');
var httpRequest = function(options){
if(!options) return new Promise((_, reject)=>{ reject( new Error('Missing \'options\' arg.'))})
if(!options.host) return new Promise((_, reject)=>{ reject( new Error('\'host\' parameter is empty.'))})
var protocol = (options.protocol || 'http').toLowerCase();
var method = (options.method || 'GET').toUpperCase();
var path = options.path || '/';
var port = options.port || (protocol == 'https' ? 443 : 80);
var _http = protocol == 'https'? https : http;
var prom = new Promise((resolve, reject)=>{
var ops = {
host : options.host, // here only the domain name
port : port,
path : (/^(\/)/i.test(path) ? '' : '/' ) + path,
headers: options.headers || {},
method : method
};
var body = options.body;
if(body && typeof(body) === 'object'){
body = JSON.stringify(body);
if(!utils.hasHeader(ops, 'Content-Type')) ops.headers['Content-Type'] = 'application/json; charset=utf-8';
if(!utils.hasHeader(ops, 'Content-Length')) ops.headers['Content-Length'] = Buffer.byteLength(body, 'utf8');
}
var req = _http.request(ops, (res)=>{
var decoder = new StringDecoder('utf-8');
var buffer = '';
res.on('data', function(data) {
buffer += decoder.write(data);
});
res.on('end', function() {
buffer += decoder.end();
if(/^(2)/i.test(res.statusCode.toString()))
resolve({statusCode : res.statusCode , data : buffer })
else
reject({statusCode : res.statusCode , error : buffer })
});
req.on('error', (err)=>{
reject({statusCode : 0, error : err});
})
req.on('timeout', (err)=>{
reject({statusCode : 0, error : new Error('Timeout exeded.')});
})
if(body) req.write(Buffer.from(body).toString('utf8'));
req.end();
});
return prom;
}