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

本文通过烽火传递信息的比喻,形象地解释了同步调用、回调及异步调用的概念及其工作原理,并提供了具体的伪代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

同步调用是以一种阻塞式调用
比如说:古代的长城的烽火传递信息,现在我们假设每个烽火只能看到相邻的烽火状态,每个烽火的状态只有亮和暗。
现在有A、B、C、D四个烽火,A首先点亮,B看到A的烽火亮了,立马去点火,花了2秒点亮。但是这时候负责C烽火的人在睡觉,可是这时候所有人都在等待C点亮,终于C睡了2个小
时候看到了B点亮,然后去点亮。D由于长期没有点亮,导致烽火出现问题,因此整个过程都在等待D的完成。
伪代码:
  1. ifAcomplete
  2. doB
  3. else
  4. waitA
  5. ifBcomplete
  6. doC
  7. else
  8. waitB
  9. ifCcomplete
  10. doD
  11. else
  12. waitC
这种就是典型的阻塞机制,无论如何我们只能等待上一个任务的完成,如果没有完成我们只能继续等待,这样造成的问题是,我们一直在浪费系统资源。

回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口
同样上面的例子:
现在我们还是A、B、C、D,但是A中有一个去B的信鸽(b),同样B中有(c),C中有(d)。现在我A收到消息后,我立马告诉信鸽b,然后自己去点亮烽火,信鸽会把信息带给B,B收 到信鸽信息后立马点亮,然后放信鸽去C,C看到B点亮后立马告诉信鸽,之后点亮烽火,然后才收到信鸽c返回的信息,最后D收到信鸽,点亮烽火。
大家应该看到了,有两种做法,一种是我可以先放信鸽(也就是先执行回调函数,然后在继续执行下面的代码),再点亮烽火。同样可以先点亮烽火再放信鸽。
伪代码:
  1. ifAMessage
  2. sendtob
  3. doA
  4. ifBMessageFromb
  5. doB
  6. sendtoc
  7. ifBcomplete
  8. sendtoD
  9. doC
  10. messagefromc
  11. ifMessageFromd
  12. doD
这种就是在函数的参数中带有一个其他函数指针,当需要的时候我们可以通过函数指针名进行调用其他函数即发送消息到其他函数。

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


伪代码:

  1. FtellA
  2. doA
  3. time2hours
  4. ifAcompleteReporttoF
  5. FtellB
  6. doB
  7. time1hours
  8. ifBcompleteReporttoF
  9. FtellC
  10. doC
  11. time1.5hours
  12. ifCcompleteReporttoF
  13. FtellD
  14. doD
  15. time3hours
  16. ifDcompleteReporttoF

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


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

例一:
[javascript] view plain copy print ?
  1. vartemp=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 plain copy print ?
  1. functionlightUp(A,callback){
  2. callback();
  3. A.lightUp();
  4. }
  5. functioncallback(){
  6. B.lightUp();
  7. }

例三:
[javascript] view plain copy print ?
  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. }

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值