了解Layman术语中的异步代码

Pin*_*ade 19 javascript asynchronous node.js

我理解异步的基本内容:事情不按顺序执行.据我所知,有一些非常强大的东西...... 但对于我的生活,我无法绕过代码.让我们来看看我写过的异步Node.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();
}
Run Code Online (Sandbox Code Playgroud)

响应又来自何处?发布数据?为什么我不能在这个"回调"中定义变量然后在回调之外使用它?有没有办法让一些东西顺序然后其余的程序异步?

Mic*_*ley 43

我不确定这个函数的使用位置,但回调的重点是你将它们传递给一些异步运行的函数; 它存储你的回调函数,当该函数完成它需要做的任何事情时,它将使用必要的参数调用你的回调函数.从前到后的一个例子可能是最好的.

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

function getStuffFromDatabase() {
  // this takes a long time
};
Run Code Online (Sandbox Code Playgroud)

由于我们不希望它同步运行,我们将允许用户传入回调.

function getStuffFromDatabase(callback) {
  // this takes a long time
};
Run Code Online (Sandbox Code Playgroud)

我们会模拟花很长时间打电话给setTimeout; 我们还假装从数据库中获取了一些数据,但我们只是对字符串值进行硬编码.

function getStuffFromDatabase(callback) {
  setTimeout(function() {
    var results = "database data";
  }, 5000);
};
Run Code Online (Sandbox Code Playgroud)

最后,一旦我们获得了数据,我们将调用框架函数的用户给我们的回调.

function getStuffFromDatabase(callback) {
  setTimeout(function() {
    var results = "database data";
    callback(results);
  }, 5000);
};
Run Code Online (Sandbox Code Playgroud)

作为框架的用户,您可以执行以下操作来使用该功能:

getStuffFromDatabase(function(data) {
  console.log("The database data is " + data);
});
Run Code Online (Sandbox Code Playgroud)

所以,你可以看到data(同responsepostData在你的例子),从你通过回调函数来 ; 当它知道该数据应该是什么时,它会将数据提供给您.

你无法在回调中设置值并在回调之外使用它的原因是因为回调本身直到晚些时候才会发生.

//  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
Run Code Online (Sandbox Code Playgroud)

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

  • 嘿,我不会说我不会再读一两次了 - 但这可能是一个人可以给出的最好的解释,而不是在这里. (3认同)
  • 我认为这是理解回调如何工作的一个很好的解释 - 谢谢! (2认同)

Thi*_*tes 8

你有几个不相关的问题:

1)异步的强大功能是能够在不锁定主线程的情况下同时执行多项操作.在节点和js中,这通常适用于ajax文件请求.这意味着我可以触发几个对retreive文件的异步调用,而不是在呈现内容时锁定主线程.我首选的框架是jQuery,它有方便的$ .Deferred,包装和标准化jQuery使用的异步调用.

2)response和postData来自父方法.这里没什么神奇的,它是一个普通的函数调用,所以这些函数的值在别处创建并传递给这个调用.根据您拥有的节点框架,您的方法的确切签名将会更改.

3)如果回调正确,您可以在回调中定义一个全局变量.虽然您需要帮助了解范围是什么.这是一些链接

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

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

4)一旦你去异步,你永远不会回头,但是,通过利用promise和延迟对象,比如jQuery Deferreds,你可以等待几个asyncs完成,然后再继续执行另一个异步.延期是你的朋友.

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

  • 我赞赏你的信心 (3认同)