我一直在读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')。
第一个应该是同步代码。
第二种是异步代码。
这两件作品之间的区别对我来说很模糊。输出是什么?
在谷歌上搜索异步编程也没什么用。
同步编程
像C, c#, Java这样的编程语言是同步编程,所以无论你写什么,都会按照你写的顺序执行。
-GET DATA FROM SQL.
//Suppose fetching data take 500 msec
-PERFORM SOME OTHER FUNCTION.
//Performing some function other will take 100 msec, but execution of other
//task start only when fetching of sql data done (i.e some other function
//can execute only after first in process job finishes).
-TOTAL TIME OF EXECUTION IS ALWAYS GREATER THAN (500 + 100 + processing time)
msec
异步
NodeJs提供了异步特性,它本质上是非阻塞的,假设在任何需要时间的I/O任务(获取,写入,读取)中,NodeJs不会保持空闲状态并等待任务完成,它会开始执行队列中的下一个任务,每当该时间任务完成时,它会使用回调通知。
下面的例子会有所帮助:
//Nodejs uses callback pattern to describe functions.
//Please read callback pattern to understand this example
//Suppose following function (I/O involved) took 500 msec
function timeConsumingFunction(params, callback){
//GET DATA FROM SQL
getDataFromSql(params, function(error, results){
if(error){
callback(error);
}
else{
callback(null, results);
}
})
}
//Suppose following function is non-blocking and took 100 msec
function someOtherTask(){
//some other task
console.log('Some Task 1');
console.log('Some Task 2');
}
console.log('Execution Start');
//Start With this function
timeConsumingFunction(params, function(error, results){
if(error){
console.log('Error')
}
else{
console.log('Successfull');
}
})
//As (suppose) timeConsumingFunction took 500 msec,
//As NodeJs is non-blocking, rather than remain idle for 500 msec, it will start
//execute following function immediately
someOtherTask();
简而言之,输出如下:
Execution Start
//Roughly after 105 msec (5 msec it'll take in processing)
Some Task 1
Some Task 2
//Roughly After 510 msec
Error/Successful //depends on success and failure of DB function execution
区别很明显,同步将花费超过600 msec(500 + 100 +处理时间),异步可以节省时间。
不同之处在于,在第一个示例中,程序将在第一行阻塞。下一行(console.log)将不得不等待。
在第二个示例中,console.log将在处理查询时执行。也就是说,查询将在后台处理,而您的程序正在做其他事情,一旦查询数据准备好了,您就可以对它做任何想做的事情。
所以,简而言之:第一个例子会阻塞,而第二个不会。
输出如下两个例子:
// Example 1 - Synchronous (blocks)
var result = database.query("SELECT * FROM hugetable");
console.log("Query finished");
console.log("Next line");
// Example 2 - Asynchronous (doesn't block)
database.query("SELECT * FROM hugetable", function(result) {
console.log("Query finished");
});
console.log("Next line");
是:
查询完成
下一行
下一行
查询完成
请注意
虽然Node本身是单线程的,但有一些任务可以并行运行。例如,文件系统操作发生在不同的进程中。
这就是Node可以执行异步操作的原因:一个线程执行文件系统操作,而主Node线程继续执行javascript代码。在事件驱动的服务器(如Node)中,文件系统线程将某些事件(如完成、失败或进展)以及与该事件相关的任何数据(如数据库查询的结果或错误消息)通知主Node线程,主Node线程决定如何处理这些数据。
你可以在这里阅读更多:单线程非阻塞IO模型如何在Node.js中工作
同步编程
像C, c#, Java这样的编程语言是同步编程,所以无论你写什么,都会按照你写的顺序执行。
-GET DATA FROM SQL.
//Suppose fetching data take 500 msec
-PERFORM SOME OTHER FUNCTION.
//Performing some function other will take 100 msec, but execution of other
//task start only when fetching of sql data done (i.e some other function
//can execute only after first in process job finishes).
-TOTAL TIME OF EXECUTION IS ALWAYS GREATER THAN (500 + 100 + processing time)
msec
异步
NodeJs提供了异步特性,它本质上是非阻塞的,假设在任何需要时间的I/O任务(获取,写入,读取)中,NodeJs不会保持空闲状态并等待任务完成,它会开始执行队列中的下一个任务,每当该时间任务完成时,它会使用回调通知。
下面的例子会有所帮助:
//Nodejs uses callback pattern to describe functions.
//Please read callback pattern to understand this example
//Suppose following function (I/O involved) took 500 msec
function timeConsumingFunction(params, callback){
//GET DATA FROM SQL
getDataFromSql(params, function(error, results){
if(error){
callback(error);
}
else{
callback(null, results);
}
})
}
//Suppose following function is non-blocking and took 100 msec
function someOtherTask(){
//some other task
console.log('Some Task 1');
console.log('Some Task 2');
}
console.log('Execution Start');
//Start With this function
timeConsumingFunction(params, function(error, results){
if(error){
console.log('Error')
}
else{
console.log('Successfull');
}
})
//As (suppose) timeConsumingFunction took 500 msec,
//As NodeJs is non-blocking, rather than remain idle for 500 msec, it will start
//execute following function immediately
someOtherTask();
简而言之,输出如下:
Execution Start
//Roughly after 105 msec (5 msec it'll take in processing)
Some Task 1
Some Task 2
//Roughly After 510 msec
Error/Successful //depends on success and failure of DB function execution
区别很明显,同步将花费超过600 msec(500 + 100 +处理时间),异步可以节省时间。
JS中的异步编程:
同步
停止执行进一步的代码,直到完成此操作。
因为它停止了进一步的执行,同步代码被称为“阻塞”。阻塞是指没有其他代码将被执行。
异步
它的执行被延迟到事件循环中,这是JS虚拟机中的一个构造,它执行异步函数(在同步函数堆栈为空之后)。
异步代码之所以称为非阻塞代码,是因为它不会阻塞进一步的代码运行。
例子:
//该函数是同步的
函数日志(参数){
console.log (arg)
}
日志(1);
//该函数是异步的
setTimeout(() => {
console.log (2)
}, 0);
日志(3)
示例记录1、3、2。
2被记录在最后,因为它在一个异步函数中,该函数在堆栈为空后执行。