了解Javascript和node.js中的回调 [英] Understanding callbacks in Javascript and node.js
问题描述
我是一个很长时间的PHP(CodeIgniter& WordPress)开发人员,只是最近想学习一些其他语言。我已经开始学习Ruby(在Rails和Sinatra),Python(w / Flask框架)和Javascript与node.js.
I'm a long time PHP (CodeIgniter & WordPress) developer that only recently wanted to learn a few other languages. I've set out to learn Ruby (on Rails, and Sinatra), Python (w/ Flask framework) and Javascript with node.js.
我决定使用这些语言创建我可以想到的最基本的应用程序,一个URL扩展器。我已经设法创建一个工作版本的每种语言,除了node.js和Javascript。
I decided to create the most basic application I can think of, a URL expander, using each of these languages. I have managed to create a working version in every language, except node.js and Javascript.
我知道我的问题,我知道它是与回调相关。我知道我不是做对了。我得到回调的基本想法,但我只是不能弄清楚如何修复我创建的这个混乱。
I kinda know my problem, I know it is related to callbacks. I know I'm not doing it right. I get the basic idea of callbacks, but I just cannot figure out how to fix this mess I have created.
这是我的整个代码:
var http = require('http');
var url = require('url');
function expand() {
var short = url.parse('http://t.co/wbDrgquZ');
var options = {
host: short.hostname,
port: 80,
path: short.pathname
};
function longURL(response) {
console.log(response.headers.location);
}
http.get(options, longURL);
}
function start() {
function onRequest(request, response) {
console.log("Request received.");
response.writeHead(200, {
"Content-Type": "text/plain"
});
response.write("Hello World");
expand();
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
start();
服务器启动,当发出请求时,它调用expand函数,在终端。我试图让它在浏览器中打印。
The server starts, and when a request is made, it calls the expand function which returns the expanded URL in the terminal. I'm trying to get it to print in the browser.
任何帮助是赞赏。提前感谢。
Any help is appreciated. Thanks in advance.
推荐答案
您有一些缺陷。
您应该重写expand以传递url并传递回调。任何异步的函数通常在节点中具有签名(data,callback)
。这基本上允许你说我想让这个函数做一些事情,然后告诉我,当它完成。
You should rewrite expand to pass the url in and pass a callback in. Any function that does anything asynchronous generally has the signature (data, callback)
in node. This basically allows you to say I want this function to do something then tell me when it's done.
function expand(urlToParse, callback) {
// note we pass in the url this time
var short = url.parse(urlToParse);
var options = {
host: short.hostname,
port: 80,
path: short.pathname
};
// note we store the clientRequest object temporarily
var clientRequest = http.get(options, extractRealURL);
// Always attach the error handler and forward any errors
clientRequest.on("error", forwardError);
function extractRealURL(res) {
callback(null, res.headers.location);
}
function forwardError(error) {
callback(err);
}
}
这里回调函数的签名为(err,data)
几乎所有的回调在节点都有。我们还添加了错误处理,这是必须的。
Here the callback is expected to have the signature of (err, data)
which almost all callbacks in node have. We've also added error handling which is a must.
现在我们改变onRequest,以实际调用扩展。
We now change onRequest to actually call expand properly
function onRequest(request, response) {
// parse the incoming url. true flag unpacks the query string
var parsedUrl = url.parse(request.url, true),
// extract the querystring url.
// http://localhost:8888/?url=http://t.co/wbDrgquZ
urlToExpand = parsedUrl.query.url;
// call expand with the url and a callback
expand(urlToExpand, writeResponse);
function writeResponse(error, newUrl) {
// handle the error case properly
if (error) {
response.writeHead(500, { 'Content-Type': 'text/plain'});
// early return to avoid an else block
return response.end(error.message);
}
response.writeHead(200, { 'Content-Type': 'text/plain'});
// write the new url to the response
response.end(newUrl);
}
}
这里我们添加了错误处理逻辑,
Here we have added error handling logic and also unpacked the actual url to expand from the query string.
通常, doSomething< data,callback< err,result>>< / code>在node.js中工作得很好。
Generally the pattern of doSomething<data, callback<err, result>>
works very well in node.js.
它与完全相同let result = doSomething< data>
It's the exact same as let result = doSomething<data> mayThrow err
that you expect in your normal blocking languages except it's asynchronous.
请注意,传递的另一个选项是, ServerResponse
对象进入函数是被皱眉的,通过这样做你在扩展函数和服务器响应之间创建不必要的硬耦合。
Note that the alternative option of passing the ServerResponse
object into the function is frowned upon, by doing so your creating unnecessary hard coupling between the expand function and the server response.
函数应该只展开一个url并返回展开的网址,它没有业务做IO本身。
The expand function should only expand an url and return the expanded url, it has no business doing IO itself.
这篇关于了解Javascript和node.js中的回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!