同步和阻塞:这两个术语可以互换使用,指的是代码的执行会在函数返回之前停止。如果某个操作阻塞,那么脚本就无法继续,这意味着必须等待。
异步和非阻塞:这两个术语可以互换使用,指的是基于回调的、允许脚本并行执行操作的方法。脚本无需等待某个操作的结果才能继续前进,因为操作结果会在事件发生时由回调来处理。使用异步方法,操作无需一个接一个地发生(自己注:就是并行了)。
@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. Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2) C. The Tower is Going Home(思维+双指针)

    https://codeforces.com/contest/1075/problem/C 题意 一个宽为1e9*1e9的矩阵中的左下角,放置一个车(车可以移动到同一行或同一列),放置一些墙,竖的占据 ...

  2. Vue + Element UI 实现权限管理系统

    Vue + Element UI 实现权限管理系统 前端篇(一):搭建开发环境 https://www.cnblogs.com/xifengxiaoma/p/9533018.html

  3. Oracle中根据当前时间和活动类型去数据库查询活动id

    活动类型默认是1,代表邀请好友 select * from t_invite_activityinfo twhere sysdate >= t.begintime and sysdate< ...

  4. Mybatis-Plus 实战完整学习笔记(六)------select测试一

    查询方法(3.0.3) 1.查询一个员工的数据 @Test public void selectMethod() throws SQLException { // 根据ID获取一个对象的数据 Empl ...

  5. MarkDown总结

    转载自:https://www.jianshu.com/p/q81RER:做了一些部分修改: 一:总纲 1.所有的格式均要空格,如#后面加个空格,-后面加空格,1.后面加空格等等: 2.双向包裹的不能 ...

  6. Effective C++ 随笔(2)

    条款5 了解c++默默编写并调用哪些函数 编译器自动生成的copy 构造函数,copy赋值操作符,析构函数,构造函数,这些都是public和inline的,此处inline的意思是他们的定义都是在头文 ...

  7. C#的math类的全部运算方法

    Abs 返回指定数字的绝对值.Acos 返回余弦值为指定数字的角度.Asin 返回正弦值为指定数字的角度.Atan 返回正切值为指定数字的角度.Atan2 返回正切值为两个指定数字的商的角度.BigM ...

  8. 恢复VS2010/VS2013项目为VS2008项目

    https://blogs.msdn.microsoft.com/rextang/2009/07/06/convert-vs2010-projects-back-to-vs2008-ones/ 摘抄如 ...

  9. uva1659(最大费用循环流)

    紫书上的一道题,做法见紫书P378,这篇博客用的第二种方法,关于正确性的证明,画图可以发现如果一个环是负环,跑最小费用流跑出的是环上的所有正边,再减去负边和即为跑一遍的负权,如果是正环,最小费用流即为 ...

  10. quartz之hello(java)

    quartz    任务调度框架 简单的说:就是在特定的时间,干指定的事件,然后具体到某个对象去做 quartz初之体验: 1.pom.xml文件(导入jar包) <dependencies&g ...