当前位置:首页>鸿蒙APP>尝试用银行排队机的等号模型理解鸿蒙arkts里的回调概念

尝试用银行排队机的等号模型理解鸿蒙arkts里的回调概念

  • 2026-10-29 13:21:22
尝试用银行排队机的等号模型理解鸿蒙arkts里的回调概念
学习ARKTS的过程中,不可避免的遇到了回调这个概念,我感觉理解起来很头疼,好久都感觉理解的似懂非懂,似是而非的。考虑到我温故而知新的学习习惯,继续尝试用在银行办理业务,或饭店等号就餐的过程,理解下回调,不当之处欢迎指正。
一、日常生活中的回调样例:银行等号模型
当我们去银行办理业务,不过随着APP的发展,去银行排队的事情也很少了,假定人很多吧,应该会发生如下场景:
  • 去门口的取号机上面取一个号码,比如说66;
  • 拿到号之后,就可以找个位置坐着休息,刷刷公众号,看看“GaussDB和他DB们 ”往期的总结,看看抖音视频号之类的;
  • 随着排在我们前面的客户业务办理完成,窗口就会叫我们的号牌(66号)时;
  • 我们带着号码去对应的银行窗口办理业务。
在这个场景,我们拿到的号牌是回调函数,记录我们办理业务的逻辑;办理业务的人是主程序,负责取等号牌,并且在号牌时间到了,办理后续的业务;银行的柜员和叫号机则是异步任务的执行者,当轮到某个号牌(比如说我们的66号)时,会广播:请66号客户到2号柜台办理业务!并且在LED屏上显示,叫号即触发回调事件。
回调的核心思路是,主程序不需要一直等待异步程序的结果返回,而是可以继续完成其他任务,只是需要取一个号牌(即注册回调),等到号时(即回调条件满足时),叫号机进行广播(触发回调),如图1所示:
图1
二、模拟银行业务的代码演示:
第一步:客户已取号,等待叫号,这时候客户可以处理其他任务,不用一直等待:
图2
第二步:银行柜员办理完前面的65号,开始叫66号:

图3

最后,业务办理完成:

图四
其中回调函数体现在步骤3中:

在调用时将() => { this.addLog(...); this.step = 4; }作为回调传递给tellerProcess。

在定义tellerProgress()函数时,指定参数为回调函数:
完整代码如下:
// BankCallbackDemoPage.etsimport { promptAction } from '@kit.ArkUI';@Entry@Componentstruct BankCallbackDemoPage {@State step: number = 0;                // 当前步骤:0未开始,1取号,2叫号,3办理中,4完成@State logMessages: string[] = [];      // 日志列表@State isProcessing: boolean = false;   // 是否正在办理中(用于按钮禁用)private timer: number | null = null;// 添加日志private addLog(message: string) {this.logMessages.push(message);  }// 清空重置private reset() {this.step = 0;this.logMessages = [];this.isProcessing = false;if (this.timer) {      clearTimeout(this.timer);this.timer = null;    }  }// 模拟柜员处理业务(异步)private tellerProcess(callback: () => void) {this.isProcessing = true;this.addLog('👨‍💼 柜员:正在为您办理业务,请稍候...');// 模拟办理耗时(2秒)this.timer = setTimeout(() => {this.addLog('✅ 柜员:业务办理完成!');this.isProcessing = false;// 办理完成,触发回调通知客户      callback();    }, 2000);  }// 处理下一步点击private onNextStep() {if (this.step === 0) {// 步骤1:客户取号this.addLog('👤 客户:取号成功,等待叫号...');this.step = 1;    } elseif (this.step === 1) {// 步骤2:柜员叫号this.addLog('👨‍💼 柜员:请A12号客户到3号窗口办理!');this.step = 2;    } elseif (this.step === 2) {// 步骤3:客户前往柜台,开始办理(异步)this.addLog('👤 客户:您好,我要办理业务。');// 将回调函数传给柜员this.tellerProcess(() => {// 这是回调函数:业务完成后执行this.addLog('👤 客户:谢谢,再见!');this.step = 4;  // 进入步骤4(完成)      });this.step = 3; // 进入办理中状态    }// 步骤4为已完成,不再响应点击  }  build() {    Column({ space: 15 }) {// 标题      Text('🏦 银行业务办理模拟器(回调演示)')        .fontSize(22)        .fontWeight(FontWeight.Bold)        .margin({ top: 20, bottom: 10 })// 当前步骤状态      Row() {if (this.step === 0) {          Text('⏳ 未开始').fontColor('#909399')        } elseif (this.step === 1) {          Text('📋 已取号,等待叫号').fontColor('#409EFF')        } elseif (this.step === 2) {          Text('🔔 已叫号,请前往窗口').fontColor('#E6A23C')        } elseif (this.step === 3) {          Text('⏰ 办理中...').fontColor('#FF6B35')        } elseif (this.step === 4) {          Text('✅ 业务办理完成').fontColor('#67C23A')        }      }      .padding(10)      .width('100%')      .backgroundColor('#F5F7FA')      .borderRadius(8)// 下一步按钮      Button('下一步')        .width(120)        .height(40)        .backgroundColor('#409EFF')        .enabled(this.step < 4 && !this.isProcessing) // 步骤4或办理中时禁用        .onClick(() => this.onNextStep())// 重置按钮      Button('重置场景')        .width(120)        .height(40)        .backgroundColor('#909399')        .onClick(() => this.reset())// 日志显示      Text('📋 执行日志:')        .fontSize(16)        .width('100%')        .textAlign(TextAlign.Start)        .margin({ top: 15 })      List() {        ForEach(this.logMessages, (msg: string, index: number) => {          ListItem() {            Text(`${index + 1}. ${msg}`)              .fontSize(14)              .padding({ left: 10, right: 10, top: 5, bottom: 5 })              .width('100%')          }        }, (msg: string, index: number) => index.toString())      }      .layoutWeight(1)      .width('100%')      .border({ width: 1, color: '#E8E8E8' })      .borderRadius(8)      .padding(5)    }    .padding(20)    .width('100%')    .height('100%')    .backgroundColor('#FFFFFF')  }  aboutToDisappear() {if (this.timer) {      clearTimeout(this.timer);    }  }}
最近小龙虾很火,您养虾了么?

最新文章

随机文章