同步调用、回调和异步调用的区别

Advertisement

同步调用是以一种阻塞式调用
比如说:古代的长城的烽火传递信息,现在我们假设每个烽火只能看到相邻的烽火状态,每个烽火的状态只有亮和暗。
现在有A、B、C、D四个烽火,A首先点亮,B看到A的烽火亮了,立马去点火,花了2秒点亮。但是这时候负责C烽火的人在睡觉,可是这时候所有人都在等待C点亮,终于C睡了2个小时候看到了B点亮,然后去点亮。D由于长期没有点亮,导致烽火出现问题,因此整个过程都在等待D的完成。
伪代码:

[plain] view plaincopyprint?

  1. if A complete
  2. do B
  3. else
  4. wait A
  5. if B complete
  6. do C
  7. else
  8. wait B
  9. if C complete
  10. do D
  11. else
  12. wait C

这种就是典型的阻塞机制,无论如何我们只能等待上一个任务的完成,如果没有完成我们只能继续等待,这样造成的问题是,我们一直在浪费系统资源。

回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口
同样上面的例子:
现在我们还是A、B、C、D,但是A中有一个去B的信鸽(b),同样B中有(c),C中有(d)。现在我A收到消息后,我立马告诉信鸽b,然后自己去点亮烽火,信鸽会把信息带给B,B收到信鸽信息后立马点亮,然后放信鸽去C,C看到B点亮后立马告诉信鸽,之后点亮烽火,然后才收到信鸽c返回的信息,最后D收到信鸽,点亮烽火。
大家应该看到了,有两种做法,一种是我可以先放信鸽(也就是先执行回调函数,然后在继续执行下面的代码),再点亮烽火。同样可以先点亮烽火再放信鸽。
伪代码:

[plain] view plaincopyprint?

  1. if A Message
  2. send to b
  3. do A
  4. if B Message From b
  5. do B
  6. send to c
  7. if B complete
  8. send to D
  9. do C
  10. message from c
  11. if Message From d
  12. do D

这种就是在函数的参数中带有一个其他函数指针,当需要的时候我们可以通过函数指针名进行调用其他函数即发送消息到其他函数。

异步调用
异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。
依然是上面的例子:
现在我们有一个将臣F,他专门负责告诉每个烽火需要去点亮
A、B、C、D四个烽火,将臣先告诉了A,然后不等A点亮,他继续告诉了B、C和D。最后A在2小时后告诉了F我完成了,B在1小时后告诉了F我完成了,C在1.5小时后告诉F完成了,而D在3小时后告诉F完成了。F收到这些信息后,才知道整个过程完成了。

伪代码:

[plain] view plaincopyprint?

  1. F tell A
  2. do A
  3. time 2 hours
  4. if A complete Report to F
  5. F tell B
  6. do B
  7. time 1 hours
  8. if B complete Report to F
  9. F tell C
  10. do C
  11. time 1.5 hours
  12. if C complete Report to F
  13. F tell D
  14. do D
  15. time 3 hours
  16. if D complete Report to F

四个程序虽然有先后次序,但是四个烽火的点亮并不会依赖前面一个烽火是否点亮。也就是我们的代码执行虽然整体上看是依次执行的,但是执行的过程中,我们并不会因为前面的代码没有执行完,而不执行。

下面我我写三个例子,大家来看一下具体每个例子是什么调用方式。

例一:

[javascript] view plaincopyprint?

  1. var temp = false;
  2. while(!temp){
  3. temp = wait(A.lightUp());
  4. }
  5. temp = false;
  6. while(!temp){
  7. temp = wait(B.lightUp());
  8. }
  9. temp = false;
  10. while(!temp){
  11. temp = wait(C.lightUp());
  12. }
  13. temp = false;
  14. while(!temp){
  15. temp = wait(D.lightUp());
  16. }

例二:

[javascript] view plaincopyprint?

  1. function lightUp(A, callback){
  2. callback();
  3. A.lightUp();
  4. }
  5. function callback(){
  6. B.lightUp();
  7. }

例三:

[javascript] view plaincopyprint?

  1. A.lightUp(){
  2. this.do();
  3. this.onComplete(this.tell(F));
  4. }
  5. B.lightUp(){
  6. this.do();
  7. this.onComplete(this.tell(F));
  8. }
  9. C.lightUp(){
  10. this.do();
  11. this.onComplete(this.tell(F));
  12. }
  13. D.lightUp(){
  14. this.do();
  15. this.onComplete(this.tell(F));
  16. }

上面三个例子大家可以自我去解答,我这里就不解答,如果想解答可以在评论说出,希望大家给出不通的理解和看法。也许我的只是个人臆想。

Similar Posts:

  • 驱动中以文件句柄形式调用其他驱动程序(异步调用二)

    EXE部分 #include <stdio.h> #include <Windows.h> #include <WinIoCtl.h> #include "Ioctl.h" int main (void) { char linkname[]="\\\\.\\HelloDDKB"; HANDLE hDevice = CreateFileA(linkname, GENERIC_READ | GENERIC_WRITE, 0, NULL

  • 同步调用、异步调用

    ----------------------------------------转帖原文部分--------------------------------- http://www.cnblogs.com/jambol/archive/2007/11/07/951798.html同步所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.按照这个定义,其实绝大多数函数都是同步调用(例如sin, isdigit等).但是一般而言,我们在说同步.异步的时候,特指那些需要其他部件协作或

  • .Net组件程序设计之异步调用

    .Net组件程序设计之异步调用 说到异步调用,在脑海中首先想到就是BeginInvoke(),在一些常用对象中我们也会常常见到Invoke()和BeginInvoke(), 要想让自己的组件可以被客户端调用或者是异步调用,这样的设计是合理的,这也是组件异步机制当中的一条 (说句题外话--其实大多数知识都隐藏在我们平时经常见到的对象或者是代码里,只不过是没有去细心的发现) 在.NET中首先就会想到使用委托来进行异步调用,关于委托的定义在 委托与事件一文中已经大概的说过了,文中只是对委托进行了 大概

  • 如何异步调用Visual C#函数How to call a Visual C# method asynchronously

    原文地址 http://support.microsoft.com/kb/315582/en-us 只翻译了我感兴趣的部分,有一些我的理解. 异步调用如何实现? 使用delegate来实现异步调用.delegate类似函数指针,和它代表的function有相同的签名,是个object.delegate提供了同步调用function,也为异步调用被代表的function提供了两个method.这两个method就是BeginInvoke()和EndInvoke(). BeginInvoke()用来

  • c#使用委托实现异步调用 [转]

    异步编程是受公共语言运行库的许多领域(如远程处理.ASP.NET 和 Windows 窗体)支持的功能.异步编程是 .NET Framework 中的核心概念.使用 .NET 异步编程,在程序继续执行的同时对 .NET 类方法进行调用,直到进行指定的回调为止:或者如果没有提供回调,则直到对调用的阻塞.轮询或等待完成为止. 异步编程是由 .NET Framework 的许多区域支持的功能,这些区域包括: 文件 IO.流 IO.套接字 IO 网络:HTTP.TCP 远程处理信道(HTTP.TCP)和

  • 深入浅出: Java回调机制(异步)

    Writer :BYSocket(泥沙砖瓦浆木匠) 什么是回调?今天傻傻地截了张图问了下,然后被陈大牛回答道"就一个回调-".此时千万个草泥马飞奔而过(逃 哈哈,看着源码,享受着这种回调在代码上的作用,真是美哉.不妨总结总结. 一.什么是回调 回调,回调.要先有调用,才有调用者和被调用者之间的回调.所以在百度百科中是这样的: 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用.回调和异步调用. 回调是一种特殊的调用,至于三种方式也有点不同. 1.同步回调,即阻

  • AJAXPro用法,关于JS同步和异步调用后台代码的学习

    一.AjaxPro的使用 1.在项目中添加引用,浏览找到AjaxPro.2.dll文件 注:关于AjaxPro.2.dll网上有得下载 2.在Web.config中的system.web里面写入以下代码 <configuration> <system.web> <httpHandlers> <add verb="*" path="*.ashx" type="AjaxPro.AjaxHandlerFactory,Aj

  • 委托的异步调用和同步调用

    委托的Invoke方法用来进行同步调用.同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行. 同步调用的例子: using System; using System.Threading; public delegate int AddHandler(int a, int b); public class Foo { static void Main() { Console.WriteLine("**********SyncInvokeTest***********

  • C# 委托的同步调用和异步调用(整理)

    C# 委托的同步调用和异步调用 委托的Invoke方法用来进行同步调用.同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行. 同步调用的例子: using System; using System.Threading; public delegate int AddHandler(int a, int b); public class Foo { static void Main() { Console.WriteLine("**********SyncInvok

  • Effective JavaScript Item 62 在异步调用中使用嵌套或者命名的回调函数

    在一开始,理解异步程序的调用顺序会有些困难.比如,下面的程序中,starting会先被打印出来,然后才是finished: downloadAsync("file.txt", function(file) { console.log("finished"); }); console.log("starting"); downloadAsync方法在执行之后会立即返回,它只是为下载这个行为注册了一个回调函数而已. 由于JavaScript"