以Layman的术语理解asynchronous代码

我理解asynchronous的基本原理:事情不会按顺序执行。 据我所知,有一些非常强大的东西。 但是对于我的生活,我无法将自己的头围绕在代码上。 让我们来看看我写的asynchronousNode.JS代码…但是并没有真正得到。

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(); } 

响应来自哪里? 发布数据? 为什么我不能在这个“callback”中定义一个variables,然后在callback之外使用它? 有没有办法让一些东西顺序,然后程序的其余部分asynchronous?

我不确定这个函数在哪里被使用,但是callback点是你将它们传递给一个asynchronous运行的函数。 它把你的callback存储起来,当这个函数完成了它所需要做的任何事情之后,它将会你需要的参数调用你的callback函数。 从前到后的例子可能是最好的。

想象一下,我们有一个框架,其中有一个运行很长时间的操作,从数据库中获取一些数据。

 function getStuffFromDatabase() { // this takes a long time }; 

由于我们不希望它同步运行,我们将允许用户传递callback。

 function getStuffFromDatabase(callback) { // this takes a long time }; 

我们将模拟需要很长时间的setTimeout调用; 我们也假装从数据库中获得了一些数据,但是我们只是硬编码一个string值。

 function getStuffFromDatabase(callback) { setTimeout(function() { var results = "database data"; }, 5000); }; 

最后,一旦我们有了数据,我们就会调用框架函数的用户给我们的callback。

 function getStuffFromDatabase(callback) { setTimeout(function() { var results = "database data"; callback(results); }, 5000); }; 

作为框架的用户,你可以使用这个函数来做这样的事情:

 getStuffFromDatabase(function(data) { console.log("The database data is " + data); }); 

所以,你可以看到data (和你的例子中的responsepostData一样)来自你传递callback函数。 当它知道数据应该是什么的时候它会把这些数据提供给你。

您无法在callback中设置值并在callback之外使用它的原因是,callback本身直到以后才会发生。

 // executed immediately executed sometime in the future // | | by getStuffFromDatabase // vv getStuffFromDatabase(function(data) { var results = data; // <- this isn't available until sometime in the future! }); console.log(results); // <- executed immediately 

console.log运行时, var results的赋值还没有发生!

你有几个无关的问题在这里:

1)asynchronous的力量可以在不locking主线程的情况下同时做多件事情。 通常在节点和js中,这尤其适用于ajax文件请求。 这意味着我可以触发几个asynchronous调用来检索文件,并且在呈现内容时不locking主线程。 我最喜欢的框架是jQuery,它有方便的$ .Deferred包装和标准化的asynchronous调用jQuery的使用。

2)response和postData来自父方法。 这里没有什么不可思议的,这是一个正常的函数调用,所以这些值是在其他地方创build的,并传递给这个调用。 根据您拥有的节点框架,您的方法的确切签名将会改变。

3)你可以在你的callback中定义一个全局variables,如果它的范围是正确的。 似乎你需要帮助了解范围是什么。 这里有一些链接

http://www.digital-web.com/articles/scope_in_javascript/

http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/

4)一旦你走asynchronous,你永远不会回去,但是,通过利用承诺和延期的对象,像jQuery Deferreds,你可以等待几个asynchronous完成,然后继续在另一个asynchronous的执行。 延期是你的朋友。

http://api.jquery.com/category/deferred-object/

看起来你正在通过Node Beginner Book 。 我鼓励你通读整本书,这真是一个很好的介绍。 如果你想更好地理解Javascript,道格拉斯·克罗克福德在YouTube上的video是一个很好的概述: 1,2 。

你发布的这段代码没有足够的上下文来帮助你。 response是一个参数,你传递给你的函数,它不是来自postData。 如果按照Node Beginner Book的build议使用代码,那么可能从createServer函数(这是Node附带的http模块的一部分)一直向下传递对newuser函数的响应。

您不能在callback中定义一个variables,然后在callback中使用它,因为Javascript是在词汇范围内的。 这里是关于Javascript范围的主题的Stack Overflowpost 。 道格·克罗克福德(Doug Crockford)发布的第一个video也对JavaScript的范围规则做了很好的解释。

JavaScript不一定是asynchronous的。 它只是提供了闭包的匿名函数,这是轻松实现asynchronous逻辑的有用工具。 同样,Node Beginner Book展示了一个用Node编写同步代码的好例子(不是你想要的),然后重写它以使其成为asynchronous。