我一直在读node初学者
我看到了下面两段代码。
第一个问题:
var result = database.query("SELECT * FROM hugetable");
console.log("Hello World");
第二点:
database.query("SELECT * FROM hugetable", function(rows) {
var result = rows;
});
console.log("Hello World");
我知道他们应该做什么,他们查询数据库来检索查询的答案。然后是console。log('Hello world')。
第一个应该是同步代码。
第二种是异步代码。
这两件作品之间的区别对我来说很模糊。输出是什么?
在谷歌上搜索异步编程也没什么用。
如果你在两个例子中都加上一行,这将变得更清楚:
var result = database.query("SELECT * FROM hugetable");
console.log(result.length);
console.log("Hello World");
第二点:
database.query("SELECT * FROM hugetable", function(rows) {
var result = rows;
console.log(result.length);
});
console.log("Hello World");
尝试运行这些程序,您将注意到第一个(同步)示例的结果。长度将在'Hello World'行之前打印出来。
在第二个(异步)示例中,结果。length将(很可能)打印在"Hello World"行之后。
这是因为在第二个例子中,数据库。查询在后台异步运行,脚本直接继续“Hello World”。console.log(result.length)只在数据库查询完成时执行。
首先,我意识到我回答这个问题有点晚了。
在讨论同步和异步之前,让我们简要地看看程序是如何运行的。
在同步情况下,每条语句在运行下一条语句之前完成。在这种情况下,程序完全按照语句的顺序求值。
这就是异步在JavaScript中的工作原理。JavaScript引擎中有两部分,一部分查看代码和队列操作,另一部分处理队列。队列处理发生在一个线程中,这就是为什么一次只能发生一个操作。
When an asynchronous operation (like the second database query) is seen, the code is parsed and the operation is put in the queue, but in this case a callback is registered to be run when this operation completes. The queue may have many operations in it already. The operation at the front of the queue is processed and removed from the queue. Once the operation for the database query is processed, the request is sent to the database and when complete the callback will be executed on completion. At this time, the queue processor having "handled" the operation moves on the next operation - in this case
console.log("Hello World");
数据库查询仍在处理中,但是console.log操作位于队列的前面并得到处理。这是一个同步操作,立即执行,结果立即输出“Hello World”。一段时间后,数据库操作完成,这时才调用和处理与查询注册的回调,并将变量result的值设置为行。
有可能一个异步操作将导致另一个异步操作,第二个操作将被放入队列中,当它到达队列的前面时,它将被处理。调用与异步操作注册的回调是JavaScript运行时在操作完成时返回操作结果的方式。
了解哪个JavaScript操作是异步的一个简单方法是注意它是否需要回调——回调是在第一个操作完成时执行的代码。在问题中的两个例子中,我们可以看到只有第二种情况有回调,所以它是两者的异步操作。但并非总是如此,因为处理异步操作结果的风格不同。
要了解更多,请阅读有关承诺的内容。承诺是处理异步操作结果的另一种方式。承诺的好处是它的编码风格更像同步代码。
许多库,如节点'fs',同时为某些操作提供同步和异步样式。在操作不需要很长时间,也不经常使用的情况下——比如读取配置文件的情况下——同步风格的操作将导致代码更容易阅读。