同步和asynchronous编程有什么区别(在node.js中)

我一直在阅读nodebeginner我碰到以下两段代码。

第一个:

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')

第一个是所谓的同步代码。 第二个是asynchronous代码。

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

使用asynchronous编程search也没有帮助我。

不同的是,在第一个例子中 ,程序将在第一行中阻塞。 下一行( 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"); 

将会:

  1. Query finished
    Next line
  2. Next line
    Query finished

注意
虽然Node本身是单线程的 ,但有一些任务可以并行运行。 例如,文件系统操作发生在不同的进程中。

这就是为什么Node可以执行asynchronous操作的原因:一个线程正在执行文件系统操作,而Node主线程继续执行您的JavaScript代码。 在像Node这样的事件驱动的服务器中,文件系统线程通知主节点线程某些事件,例如完成,失败或进度,以及与该事件相关的任何数据(例如数据库查询的结果或错误消息),主节点线程决定如何处理这些数据。

你可以在这里阅读更多关于这个: 单线程非阻塞IO模型如何在Node.js中工作

这两种方法的区别如下:

同步方式:等待每个操作完成,之后只执行下一个操作。 对于您的查询: console.log()命令将不会被执行,直到&,除非查询已经完成执行从数据库获得所有的结果。

asynchronous方式:从不等待每个操作完成,而是只执行第一个GO中的所有操作。 一旦结果可用,每个操作的结果将被处理。 对于您的查询: console.log()命令将在Database.Query()方法后不久执行。 数据库查询在后台运行,并在完成检索数据后加载结果。

用例

  1. 如果您的操作不像DB查询大量数据那样非常繁重,那么就采用同步方式,否则采用asynchronous方式。

  2. 在asynchronous的方式,你可以显示一些进度指示给用户,而在后台,你可以继续你的沉重的作品。 这是GUI应用程序的理想场景。

如果您将两行添加到两个示例,这将变得更加清晰:

 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"); 

试着运行这些,你会注意到第一个(同步的)例子,result.length会在'Hello World'行之前被打印出来。 在第二个(asynchronous)示例中,result.length将(最有可能)在“Hello World”行后面打印。

这是因为在第二个例子中, database.query在后台asynchronous运行,并且脚本继续与“Hello World”连接。 console.log(result.length)仅在数据库查询完成时执行。

首先,我意识到我迟迟未能回答这个问题。

在讨论同步和asynchronous之前,让我们简单看一下程序如何运行。

同步的情况下,每个语句在下一个语句运行之前完成 。 在这种情况下,程序完全按照报表的顺序进行评估。

这是在JavaScript中如何asynchronous工作。 JavaScript引擎中有两部分,一部分是查看代码和排队操作,另一部分是处理队列。 队列处理发生在一个线程中,这就是为什么一次只能执行一个操作的原因。

当看到一个asynchronous操作(如第二个数据库查询)时,代码被parsing并且操作被放入队列中,但是在这种情况下,当这个操作完成时,注册一个callback被执行。 队列中可能有许多操作。 队列前面的操作被处理并从队列中移除。 一旦处理完数据库查询的操作,就会将请求发送到数据库,完成后callback将在完成时执行。 此时,处理该操作的队列处理器在下一个操作中移动 – 在这种情况下

  console.log("Hello World"); 

数据库查询仍在处理中,但console.log操作位于队列的前端并进行处理。 这是一个同步操作立即执行立即在输出“你好世界”。 一段时间后,数据库操作完成,只有那些调用和查询注册的callback被调用和处理,将variables结果的值设置为行。

有可能是一个asynchronous操作会导致另一个asynchronous操作,第二个操作将被放入队列中,当它到达队列的前端时,将被处理。 调用使用asynchronous操作注册的callback是JavaScript运行时如何在完成操作时返回操作的结果。

知道哪个JavaScript操作是asynchronous的简单方法是注意是否需要callback – callback是在第一个操作完成时将被执行的代码。 在这个问题的两个例子中,我们可以看到只有第二种情况有callback,所以是两者的asynchronous操作。 处理asynchronous操作结果的风格并不总是这样。

要了解更多信息,请阅读有关承诺。 承诺是asynchronous操作的结果可以被处理的另一种方式。 承诺的好处是编码风格更像同步代码。

许多类似节点“fs”的库为某些操作提供同步和asynchronous样式。 在操作不需要很长时间而又不常用的情况下(比如在读取configuration文件的情况下),同步样式操作将导致代码更容易阅读。

在同步情况下,在SQL查询执行完成之前,不会执行console.log命令。

在asynchronous情况下,console.log命令将被直接执行。 查询的结果将在稍后由“callback”function存储。

主要区别在于asynchronous编程,否则不要停止执行。 您可以在“请求”正在执行时继续执行其他代码。

该function使第二个asynchronous。

第一个强制程序等待每一行完成它的运行,然后下一个可以继续。 第二个允许每条线路一起运行(独立运行)。

允许asynchronous或并发的语言和框架(js,node.js)对需要实时传输的事物(例如聊天,股票应用程序)来说是非常好的。