同步和阻塞:这两个术语可以互换使用,指的是代码的执行会在函数返回之前停止。如果某个操作阻塞,那么脚本就无法继续,这意味着必须等待。
异步和非阻塞:这两个术语可以互换使用,指的是基于回调的、允许脚本并行执行操作的方法。脚本无需等待某个操作的结果才能继续前进,因为操作结果会在事件发生时由回调来处理。使用异步方法,操作无需一个接一个地发生(自己注:就是并行了)。
@1 同步和阻塞的例子:
    function sleep(milliseconds) {
      var start = new Date().getTime();
      while ((new Date().getTime() - start) < milliseconds){ }
    }
 
    function fetchPage() {
      console.log('fetching page');
      sleep(2000); // simulate time to query a database
      console.log('data returned from requesting page');
    }
 
    function fetchApi() {
      console.log('fetching api');
      sleep(2000); // simulate time to fetch from an api
      console.log('data returned from the api');
    }
    fetchPage();
    fetchApi();
 
@2 异步和非阻塞方式的例子:
    $(function () {
        $('p').hide(5000, function() {
              alert("The paragraph is now hidden");
        });
       console.log("测试");
    });
 
@3 常用的同步回调
    function haveBreakfast(food, drink, callback) {
      console.log('Having breakfast of ' + food + ', ' + drink);
      if (callback && typeof(callback) === "function") {
       sleep(2000);
        callback();
      }
    }
    function sleep(milliseconds) {
      var start = new Date().getTime();
      while ((new Date().getTime() - start) < milliseconds){  }
    }
 
    haveBreakfast('toast', 'coffee', function() {
      console.log('Finished breakfast. Time to go to work!');
    });
    console.log("如果是回调的话,Finished会在这个之后显示");//结果是最后显示
    首先说下,什么是回调:
        回调指的是将一个函数作为参数传递给另一个函数,并且通常在第一个函数完成后被调用。
 
    在JavaScript中,函数可以作为参数传递到另一个函数中,然后被调用。这个突然让我想起了C#的"委托",只是将方法传递给另一个函数进行执行,当然在学委托时,还是感觉很牛叉的。@3是同步的回调函数,无可厚非,console.log需要等待上面脚本执行。
 
    @3并不是node.js中说的回调函数。node.js是异步、非阻塞的,回调的意义在于函数调用后执行, 且下面的脚本无需等待某个操作的结果才能继续下去。回调常用于处理的函数的操作结果。
    接下来就说下我们以前接触到的回调。
    相信大家都使用过jQuery,我们在jQuery中经常使用回调,最常见的就是Ajax(异步的)中的success:function(data){…代码…},调试过这段代码的都知道,Ajax后面的脚本可以在success回调之前执行。在@2中也是如此,console.log()会在动画完成之前执行,不必等待。
    如果了解xmlhttprequest异步的话,会知道它有四个状态来判断是否请求完成。想象下Ajax的过程,前台向后台请求数据,后台会返回状态给前台,当状态为成功时,会去调用success中的函数。简单的说,获得数据,通知前台,前台调用success函数。当然别忘了,Ajax是异步的,请求可以是多个!至于多个请求响应的先后顺序、前台的回调挂哪,成功后怎么调回调等,咱们不关心,重点是知道回调这个概念! 至于具体实现的,此处不关心。
    如果将jQuery的Ajax进行假设,假设它只许成功、请求需要的路径等都是已知的。这时我们可以抽象为jQuery.Ajax({data:'data'},function(success){…代码…}),此时和动画进行简单修改jQuery.hide('slow', function(success) {…代码…}),然后进行类比,会发现它们有一些共通点:
        第一:只需要参数就能进行函数的调用,回调并不是必须的。 jQuery.Ajax只需要data参数就能进行请求;jQuery.hide只需要知道时间(speed),就能进行动画操作。
        第二:都是调用函数执行完后,后续操作交由回调函数执行的(匿名)。
        第三:不阻塞后面的代码。
    理解此处对于node的匿名函数有帮助。
    
    Node.js到处使用回调(异步调用回调),尤其在有I/O操作发生的地方。Node.js运行在单一的进程中,并且要求开发人员使用异步编程风格
 
    那么Node.js是怎么实现异步的编程风格呢?我们写的代码是异步的吗?
    Node.js使用JavaScript的事件循环来支持它所推崇的异步编程风格。事件循环使得循环可以将回调先保存起来,而后当事件在将来发生时再运行。也就是说,回调是Node.js实现编程的关键方法,因为回调让代码在其他事件发生的时候运行。Node.js的设计旨在处理网络中数据流的不确定性,促成这样的设计是JavaScript的事件循环和对回调的使用,这使得程序员可以编写对网络或I/O事件进行响应的异步代码。这也就是说编写的代码一般都是异步的。(jQuery绑定事件都有都有回调吧?)。
 
    
Node.js一些特点:
    Node的关键思想是,将代码围绕着事件来架构,而不是按照期待中的输入顺序来架构。
    Node的核心哲学是在事件循环和单一进程的上下文中尝试并编程。
    Node.js进程在还有已经注册的回调尚未触发之前将不会退出。
    Node.js将事件循环用于到服务器端的编程上,尤其是在网络和I/O操作的上下文中,Node.js经常被当成是一个网络编程框架,因为它的设计旨在处理网络中数据流的不确定性。
    Node.js所不适合的地方包括处理大量数据或者长时间运行计算等。Node.js旨在网络中推送数据并瞬间完成。
 
在使用回调的时候可能会遇到哪些问题?
    在使用回调时可能碰到与控制流相关的问题。在这里需要指定回调的执行顺序。可能发现回调的嵌套深度会多达4到5层,嵌套过多可能会碰到深度嵌套的回调和控制流的问题。

附:请求对象和事件循环

node.js中的回调的更多相关文章

  1. 初步揭秘node.js中的事件

    当你学习node.js的时候,Events是一个非常重要的需要理解的事情.非常多的Node对象触发事件,你能在文档API中找到很多例子.但是关于如何写自己的事件和监听,你可能还不太清楚.如果你不了解, ...

  2. Node.js权威指南 (10) - Node.js中的错误处理与断言处理

    10.1 使用domain模块处理错误 / 272 10.1.1 domain模块概述 / 272 10.1.2 创建并使用Domain对象 / 274 10.1.3 隐式绑定与显式绑定 / 276 ...

  3. node.js如何使用回调

    Node.js到处使用回调,尤其在有I/O(输入/输出)操作的地方. 下面是在一个Node.js中使用filesystem模块中从磁盘上读入文件内容示例一: var fs = require('fs' ...

  4. node.js中process进程的概念和child_process子进程模块的使用

    进程,你可以把它理解成一个正在运行的程序.node.js中每个应用程序都是进程类的实例对象. node.js中有一个 process 全局对象,通过它我们可以获取,运行该程序的用户,环境变量等信息. ...

  5. node.js中通过dgram数据报模块创建UDP服务器和客户端

    node.js中 dgram 模块提供了udp数据包的socket实现,可以方便的创建udp服务器和客户端. 一.创建UDP服务器和客户端 服务端: const dgram = require('dg ...

  6. node.js中net网络模块TCP服务端与客户端的使用

    node.js中net模块为我们提供了TCP服务器和客户端通信的各种接口. 一.创建服务器并监听端口 const net = require('net'); //创建一个tcp服务 //参数一表示创建 ...

  7. node.js中stream流中可读流和可写流的使用

    node.js中的流 stream 是处理流式数据的抽象接口.node.js 提供了很多流对象,像http中的request和response,和 process.stdout 都是流的实例. 流可以 ...

  8. node.js中fs文件系统模块的使用

    node.js中为我们提供了fs文件系统模块,实现对文件或目录的创建,修改和删除等操作. fs模块中,所有的方法分为同步和异步两种实现. 有 sync 后缀的方法为同步方法,没有 sync 后缀的方法 ...

  9. 在Node.js中操作文件系统(一)

    在Node.js中操作文件系统 在Node.js中,使用fs模块来实现所有有关文件及目录的创建,写入及删除操作.在fs模块中,所有对文件及目录的操作都可以使用同步与异步这两种方法.比如在执行读文件操作 ...

随机推荐

  1. 2018.11.24 spoj New Distinct Substrings(后缀数组)

    传送门 双倍经验(弱化版本) 考虑求出来heightheightheight数组之后用增量法. 也就是考虑每增加一个heightheightheight对答案产生的贡献. 算出来是∑∣S∣−heigh ...

  2. 2018.10.23 hdu2476String painter(区间dp)

    传送门 一道挺妙的区间dp. 我们先用区间dp求出第一个串为空串时的最小代价. 然后再加入原本的字符更新答案就行了. 代码: #include<bits/stdc++.h> using n ...

  3. php 操作redis 以及几个常用命令

    redis-cli -h host -p port -a password 首次进入redis 进行绑定ip和端口号   del key 删除指定key   exists key 检查指定key是否存 ...

  4. lambda表达式,变量作用域

    # lambda表达式 def filter_lt(predidcate,lt): result=[] for elem in lt: if predidcate(elem): result.appe ...

  5. Edifact 95B报文解读

    PART 1 INTRODUCTION D100_D.95B PART 2 UNIFORM RULES OF CONDUCT FOR INTERCHANGE PART2_D.ZIP(1) OF TRA ...

  6. 《深入浅出MFC》系列之动态创建

    /*************************************************************************************************** ...

  7. 使用 alt_disk_copy 克隆 rootvg

    地址:http://www.ibm.com/developerworks/cn/aix/library/au-alt_disk_copy/ 简介 大多数系统管理员都遇到过以下情况: 一次 ML 升级失 ...

  8. 1098 Insertion or Heap Sort

    1098 Insertion or Heap Sort (25 分) According to Wikipedia: Insertion sort iterates, consuming one in ...

  9. day35(servlet 3.0)

    servlet3.0的问题 Servlet3.0与Servlet2.5提供了三个新特性: * 注解开发   :方便 * 文件上传   :有些API不是特别全. * 异步请求   :多线程的实现 注解开 ...

  10. hide handkerchief

    Problem Description The Children’s Day has passed for some days .Has you remembered something happen ...