Javascript 使用导入的异步方法,并在主入口点提供承诺
我正在使用异步方法创建Node.js模块——一个简单的HTTP GET请求。代码如下:Javascript 使用导入的异步方法,并在主入口点提供承诺,javascript,node.js,promise,Javascript,Node.js,Promise,我正在使用异步方法创建Node.js模块——一个简单的HTTP GET请求。代码如下: //mymodule.js var https = require('https'); function getSomething(url_str) { var callback_fn = function(response){ var body = ''; response.on('data', function (data) { body
//mymodule.js
var https = require('https');
function getSomething(url_str)
{
var callback_fn = function(response){
var body = '';
response.on('data', function (data) {
body += data;
});
response.on('end', function () {
//console.log(body);
return body;
});
};
return https.request(url_str, callback_fn).end();
}
var module_obj = {
getSome: getSomething
};
module.exports = module_obj;
此模块由my app.js调用—一个web服务器—如下所示:
//app.js
var myModule = require('./mymodule');
var http = require('http');
var qs = require('querystring');
var server_fn = function(request, response){
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Request-Method', '*');
response.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
response.setHeader('Access-Control-Allow-Headers', '*');
if ( request.method === 'OPTIONS' ) {
response.writeHead(200);
response.end();
return;
}
if (request.method == 'POST') {
var body = '';
request.on('data', function (data) {
body += data;
// Too much POST data, kill the connection!
// 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
if (body.length > 1e6)
request.connection.destroy();
});
request.on('end', function () {
var post = qs.parse(body),
post_url = post.url,
post_method = post.method;
var promise_flow = new Promise(function(resolve, reject){
if(post_method === 'get_me_something')
{
response_str = myModule.getSome(post_url);
resolve(response_str);
}
else
{
resolve('nothing');
}
});
promise_flow
.then(function(response){
response.write(response);
response.end();
return;
}).catch(function(error){
response.write(error);
response.end();
return;
})
});
}
};
var http_server = http.createServer(server_fn);
http_server.listen(2270);
console.log("server listening on 2270");
所以基本上,我通过node app.js
启动程序,然后发布URL,然后模块应该获取网页,然后返回内容
不幸的是,我遇到以下错误:
UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: First argument must be a string or Buffer
我相信这是因为我从模块getSomething
方法得到的响应是false
,而不是请求的网页内容
我知道我可以通过从mymodule.js
移动https.get
操作,将其与app.js
内联,然后调用resolve
来解决这个问题,但我想保留当前的模块设置
在导入的模块中,是否有一种变通方法可以让异步方法在设置时与现有的承诺链一起工作
更新
经过进一步的检查,我发现我并没有按照正确的方式运行。我将代码更新如下:
//...
var promise_flow = new Promise(function(resolve, reject){
if(post_method === 'get_me_something')
{
myModule.getSome(post_url)
.then(function(data){
resolve(data);
})
.catch(function(err){
reject(err);
});
}
else
{
resolve('nothing');
}
});
//...
这样,我认为它符合承诺的真正精神 您的
getSomething
函数不会返回承诺。让它返回一个承诺,并在response.on('end')
中履行承诺
然后在主文件中,像这样调用它:
myModule.getSomething(post\uurl)
不应该myModule.getSomething(post\uURL)
bemyModule.getSome(post\uurl)代码>,还是打字错误?因为您导出的是getSome
,而不是getSomething
。这一定是一个输入错误,因为代码可能会出现类似于myModule的错误。getSomething
不是一个函数。您试图从异步getSomething
函数返回什么?@SamuelBolduc是的,这是一个输入错误。现在修好了。请解释一下downvoteWorks的魅力。谢谢。它实际上可以在没有主文件更新建议的情况下工作。没错,我没有考虑过,但是response\u str
是一个未兑现的承诺,因为resolve
知道如何处理未兑现的承诺。旁注:response\u str
由于包含承诺而不是字符串,因此成为一个模棱两可的变量名!
function getSomething(url_str)
{
return new Promise(function(resolve, reject) {
var callback_fn = function(response){
var body = '';
response.on('data', function (data) {
body += data;
});
response.on('end', function () {
//console.log(body);
resolve(body);
});
};
https.request(url_str, callback_fn).end();
});
}