后一个任务等待前一个任务结束再执行。程序执行顺序与任务排列顺序一致的,同步的。

参考:

  http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html

  https://segmentfault.com/q/1010000000140970

在JavaScript中,回调函数具体的定义为:函数A作为参数(函数引用)传递到另一个函数B中,并且这个函数B执行函数A。我们就说函数A叫做回调函数。如果没有名称(函数表达式),就叫做匿名回调函数。

因此callback 不一定用于异步,一般同步(阻塞)的场景下也经常用到回调,比如要求执行某些操作后执行回调函数。

1、一个同步(阻塞)中使用回调的例子

var func1=function(callback){//do something.(callback && typeof(callback) === "function") &&callback();
}var func2=function(){}
func1(func2);

2、改进为异步操作,不阻塞。异步编程的方法一:回调函数

functionf1(callback){setTimeout(function() {//f1的任务代码
      callback();},1000);}
f1(f2)

采用这种方式,我们把同步操作变成了异步操作,f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行。

回调函数的优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),流程会很混乱,而且每个任务只能指定一个回调函数。

3、回调总结

异步回调的例子:

$(document).ready(callback);$.ajax({url:"test.html",context: document.body
}).done(function() { $(this).addClass("done");
}).fail(function() { alert("error");
}).always(function() { alert("complete");
});/**
注意的是,ajax请求确实是异步的,不过这请求是由浏览器新开一个线程请求,当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到 JavaScript引擎的处理队列中等待处理。见:http://www.phpv.net/html/1700.html*/

回调什么时候执行

回调函数,一般在同步情境下是最后执行的,而在异步情境下有可能不执行,因为事件没有被触发或者条件不满足。

回调函数的使用场合

  • 资源加载:动态加载js文件后执行回调,加载iframe后执行回调,ajax操作回调,图片加载完成执行回调,AJAX等等。
  • DOM事件及Node.js事件基于回调机制(Node.js回调可能会出现多层回调嵌套的问题)。
  • setTimeout的延迟时间为0,这个hack经常被用到,settimeout调用的函数其实就是一个callback的体现
  • 链式调用:链式调用的时候,在赋值器(setter)方法中(或者本身没有返回值的方法中)很容易实现链式调用,而取值器(getter)相对来说不好实现链式调用,因为你需要取值器返回你需要的数据而不是this指针,如果要实现链式方法,可以用回调函数来实现
  • setTimeout、setInterval的函数调用得到其返回值。由于两个函数都是异步的,即:他们的调用时序和程序的主流程是相对独立的,所以没有办法在主体里面等待它们的返回值,它们被打开的时候程序也不会停下来等待,否则也就失去了setTimeout及setInterval的意义了,所以用return已经没有意义,只能使用callback。callback的意义在于将timer执行的
  • 结果通知给代理函数进行及时处理。

回调函数的传递

上面说了,要将函数引用或者函数表达式作为参数传递。

  • $.get('myhtmlpage.html', myCallBack);//这是对的
    $.get('myhtmlpage.html', myCallBack('foo', 'bar'));//这是错的,那么要带参数呢?
    $.get('myhtmlpage.html', function(){//带参数的使用函数表达式
    myCallBack('foo', 'bar');
    });

    另外,最好保证回调存在且必须是函数引用或者函数表达式:
    (callback && typeof(callback) === "function") && callback();

4、异步编程的方法二:事件监听(和发布订阅模式原理一样)

事件监听:

var doc =$(document);functionf2(){console.log("done");}functionf1(){setTimeout(function(){doc.trigger("done")},1000);}doc.on("done", f2);f1();

发布订阅:和事件监听一模一样啊。

观察者模式所做的工作就是在解耦,让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响到另一边的变化。

var Observable ={//doccallbacks: [],add:function(fn) {this.callbacks.push(fn);},fire:function() {this.callbacks.forEach(function(fn) {fn();})}
}
Observable.add(function() {alert(1)
})Observable.add(function() {alert(2)
})
Observable.fire();//1, 2

4、异步编程的方法三:promise对象

Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。

简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成:

  f1().then(f2);

f1要进行如下改写(这里使用的是jQuery的实现):

  function f1(){

    var dfd = $.Deferred();

    setTimeout(function () {

      // f1的任务代码

      dfd.resolve();

    }, 500);

    return dfd.promise;

  }

这样写的优点在于,回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。

比如,指定多个回调函数:

 f1().then(f2).then(f3);

再比如,指定发生错误时的回调函数:

  f1().then(f2).fail(f3);

而且,它还有一个前面三种方法都没有的好处:如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。这种方法的缺点就是编写和理解,都相对比较难。

转载于:https://www.cnblogs.com/darr/p/5207593.html

javascript的回调函数 同步 异步相关推荐

  1. javascript利用回调函数解决异步困扰

    虽然已经存在promise,StratifiedJS等工具用来解决回调地狱,但是讲真,我觉得他们也并没有让代码的可读性大大增强,而且在回调函数的嵌套次数有限的情况下也不至于成为一个"地狱&q ...

  2. 有关JavaScript中回调函数的所有内容!

    作者:Shadeed 译者:前端小智 来源:dmitripavlutin 点赞再看,微信搜索**[大迁世界],B站关注[前端小智]**这个没有大厂背景,但有着一股向上积极心态人.本文 GitHub h ...

  3. JavaScript:回调函数(callback)

    前言 callback,大家都知道是回调函数的意思.如果让你举些callback的例子,我相信你可以举出一堆.但callback的概念你知道吗?你自己在实际应用中能不能合理利用回调实现功能? 我们在平 ...

  4. 如何用JavaScript的回调函数做出承诺

    by Adham El Banhawy 由Adham El Banhawy 如何用JavaScript的回调函数做出承诺 (How to make a Promise out of a Callbac ...

  5. 彻底理解JavaScript中回调函数 (推荐)

    在javascript中回调函数非常重要,它们几乎无处不在.像其他更加传统的编程语言都有回调函数概念,但是非常奇怪的是,完完整整谈论回调函数的在线教程比较少,倒是有一堆关于call()和apply() ...

  6. ajax回调函数有时成功有时失败,javascript - Ajax 回调函数行为随机。我做错了什么?...

    我有以下行为随机的 ajax 函数.有时会显示警报 success finally.在其他情况下,第二个警报是 显示 Failure: my status is 500. promptId 从调用函数 ...

  7. js回调函数获取异步返回值

    js回调函数获取异步返回值 1.尝试获取异步返回值 function test(){var res = 0;setTimeout(function(){res = 1;},1000)return re ...

  8. 回调函数 同步回调 异步回调

    回调函数 回调函数一般是在封装接口的时候,回调显得特别重要,我们首先假设有两个程序员在写代码,A程序员写底层驱动接口,B程序员写上层应用程序,然而此时底层驱动接口A有一个数据d需要传输给B,此时有两种 ...

  9. javascript之回调函数小知识

    Javascript异步编程方法------"回调函数" 这是异步编程最基本的方法. 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用.回调和异步调用. ...

最新文章

  1. 复习计算机网络day2
  2. LeetCode1117. Building H2O --Java解法--多线程保证执行顺序--AtomicInteger
  3. 如何取消linux响铃_linux初学者入门:VIM编辑简易指南(常用操作)
  4. One Switch for Mac 一键切换系统各项功能
  5. 虚幻填坑004:减少starter content占用空间,只保留使用的assets
  6. CTFshow 反序列化 web272
  7. matplotlib xticks yticks
  8. Nginx配置https和wss
  9. 《那些年啊,那些事——一个程序员的奋斗史》——54
  10. 艰苦的编译boost python (失败)
  11. Android TextView文字超出一屏不能显示其它的文字 解决方案
  12. Android widget开发有感
  13. 你的目的是什么是谁指使你_魔家四将的师傅是谁?隐藏的高人,只配合太上老君的布局...
  14. 线程并行化的概念及其用法
  15. 基于公网smtp协议实现邮件服务器
  16. 资深技术专家张荣华:架构的方法论
  17. AAAI 2020上的NLP有哪些研究风向?
  18. 白盒测试哪种测试效果好_比较常用的白盒测试工具有哪些?
  19. 深度学习--- GAN网络原理解析
  20. 商务统计_5 用图表演示数据 - 茎叶图

热门文章

  1. 一文带你读懂单目视觉SLAM数据关联优化
  2. 《Python编程从入门到实践》记录之Python函数传递任意数量的实参
  3. 想学数学建模???先来看会这几个MATLAB题吧!!!(一)
  4. python处理mat数据_python读取.mat文件的数据及实例代码
  5. Linux gedit
  6. linux 命令如何输入,Linux 命令行输入
  7. Redis入门(三)Redis的基本数据类型
  8. 使用uiautomator2进行webview页面的测试
  9. An invalid form control with name='timeone[]' is not focusable.
  10. sql 查询所有数据库-表-表结构