通俗地理解异步代码
我了解异步的基本原理:事情不会按顺序执行.我知道这有一些非常强大的东西……据说.但是对于我的生活,我无法将我的头包裹在代码上.让我们看一下我已经编写的异步 Node.JS 代码......但并没有真正得到.
I understand the basic thing about asynchronous-ness: things don't execute sequentially. And I understand there is something very powerful about that... allegedly. But for the life of me I can't wrap my head around the code. Let's take a look at async Node.JS code that I HAVE WRITTEN...but don't truly get.
function newuser(response, postData) {
console.log("Request handler 'newuser' was called.");
var body = '<html>' +
'<head>' +
'<meta http-equiv="Content-Type" content="text/html; ' +
'charset=UTF-8" />' +
'</head>' +
'<body>' +
'<form action=" /thanks" method="post">' +
'<h1> First Name </h1>' +
'<textarea name="text" rows="1" cols="20"></textarea>' +
'<h1> Last Name </h1>' +
'<textarea name="text" rows="1" cols="20"></textarea>' +
'<h1> Email </h1>' +
'<textarea name="text" rows="1" cols="20"></textarea>' +
'<input type="submit" value="Submit text" />' +
'</body>' +
'</html>';
response.writeHead(200, { "Content-Type": "text/html" });
response.write(body);
response.end();
}
回复又是从哪里来的?发布数据?为什么我不能在这个回调"中定义一个变量,然后在回调之外使用它?有没有办法让一些事情是顺序的,然后程序的其余部分是异步的?
Where did response come from again? postData? Why can't I define a variable in this "callback" and then use it outside of the callback? Is there a way to have a few things be sequential then the rest of the program async?
推荐答案
我不确定这个函数在哪里被使用,但是回调的重点是你将它们传递给一些异步运行的函数;它将你的回调存储起来,当该函数完成它需要做的任何事情时,它会调用你的回调并带有必要的参数.从前到后的例子可能是最好的.
I'm not sure where this function is being used, but the point of callbacks is that you pass them into some function that runs asynchronously; it stores your callback away, and when that function is done with whatever it needs to do, it will call your callback with the necessary parameters. An example from front-to-back is probably best.
假设我们有一个框架,其中有一个运行很长时间的操作,从数据库中获取一些数据.
Imagine we have a framework, and in it there is an operation that runs for a long time, fetching some data from the database.
function getStuffFromDatabase() {
// this takes a long time
};
由于我们不希望它同步运行,我们将允许用户传入回调.
Since we don't want it to run synchronously, we'll allow the user to pass in a callback.
function getStuffFromDatabase(callback) {
// this takes a long time
};
我们将通过调用 setTimeout
来模拟花费很长时间;我们也会假装我们从数据库中获得了一些数据,但我们只是硬编码一个字符串值.
We'll simulate taking a long time with a call to setTimeout
; we'll also pretend we got some data from the database, but we'll just hardcode a string value.
function getStuffFromDatabase(callback) {
setTimeout(function() {
var results = "database data";
}, 5000);
};
最后,一旦我们有了数据,我们将调用框架函数的用户给我们的回调.
Finally, once we have the data, we'll call the callback given to us by the user of the framework's function.
function getStuffFromDatabase(callback) {
setTimeout(function() {
var results = "database data";
callback(results);
}, 5000);
};
作为框架的用户,您可以执行以下操作来使用该功能:
As a user of the framework, you'd do something like this to use the function:
getStuffFromDatabase(function(data) {
console.log("The database data is " + data);
});
因此,您可以看到 data
(与您的示例中的 response
和 postData
相同)来自您传递回调的函数进入;当它知道该数据应该是什么时,它会将该数据提供给您.
So, as you can see data
(same as response
and postData
in your example) came from the function that you pass your callback into; it gives that data to you when it knows what that data should be.
您不能在回调中设置值并在回调之外使用它的原因是回调本身直到稍后才会发生.
The reason you can't set a value in your callback and use it outside the callback is because the callback itself doesn't happen until later in time.
// executed immediately executed sometime in the future
// | | by getStuffFromDatabase
// v v
getStuffFromDatabase(function(data) {
var results = data; // <- this isn't available until sometime in the future!
});
console.log(results); // <- executed immediately
console.log
运行时,var results
的赋值还没有发生!
When the console.log
runs, the assignment of var results
hasn't happened yet!
相关文章