我一直在读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')。

第一个应该是同步代码。 第二种是异步代码。

这两件作品之间的区别对我来说很模糊。输出是什么?

在谷歌上搜索异步编程也没什么用。


当前回答

在同步情况下,console.log命令直到SQL查询执行完毕才执行。

异步情况下,将直接执行console.log命令。查询的结果稍后会被“回调”函数存储。

其他回答

如果你在两个例子中都加上一行,这将变得更清楚:

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)只在数据库查询完成时执行。

不同之处在于,在第一个示例中,程序将在第一行阻塞。下一行(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中工作

这两种方法的区别如下:

同步方式: 它等待每个操作完成,之后只执行下一个操作。 如有查询: console.log()命令直到&才会执行,除非查询已经完成从Database中获取所有结果。

异步方式: 它从不等待每个操作完成,而是只在第一个GO中执行所有操作。一旦结果可用,就会处理每个操作的结果。 如有查询: console.log()命令将在Database.Query()方法之后很快执行。而数据库查询在后台运行,并在检索数据完成后加载结果。

用例

如果你的操作不是很繁重,比如从DB中查询大量数据,那么就使用同步方式,否则就使用异步方式。 在异步方式中,你可以向用户显示一些进度指示器,而在后台你可以继续你的繁重工作。这是GUI应用程序的理想场景。

主要的区别是异步编程,否则你不会停止执行。当“请求”被发出时,您可以继续执行其他代码。

同步编程

像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 +处理时间),异步可以节省时间。