鸿蒙开发中 单线程异步(2)

本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

一、单线程异步理解

想象一个只有1个收银员的快餐店:

同步模式(愚蠢的做法)
  1. 顾客A点了一份现做的汉堡
  2. 收银员站在厨房等汉堡做好(10分钟)
  3. 这期间其他顾客全部干等着
  4. 汉堡好了才处理下一个顾客

结果:队伍排到店外,顾客投诉

异步模式(聪明的做法)
  1. 顾客A点汉堡后,收银员说:"好了叫您,请旁边稍等"
  2. 立即处理顾客B的薯条订单(立即可取)
  3. 顾客C要可乐,直接给
  4. 汉堡做好了回调顾客A

结果:虽然只有1个收银员,但处理效率极高

二、JavaScript的单线程异步原理

1. 核心三件套
部件作用快餐店类比
调用栈执行同步代码收银员当前正在处理的任务
任务队列存放待执行的回调取餐区的已完成订单
事件循环检查并执行回调收银员不断查看取餐区的流程
2. 工作流程
console.log("点餐开始"); // 同步任务

// 异步任务(点汉堡)
setTimeout(() => {
  console.log("汉堡好了");
}, 1000);

console.log("继续服务其他顾客"); // 同步任务

执行顺序

  1. 打印"点餐开始"(同步)
  2. setTimeout回调注册到Web APIs,开始计时
  3. 打印"继续服务其他顾客"(同步)
  4. (1秒后)计时结束,回调进入任务队列
  5. 事件循环发现调用栈为空,执行回调
  6. 打印"汉堡好了"

三、鸿蒙的增强设计

鸿蒙在标准JS引擎上增加了多线程能力

1. 三种线程类型
线程类型作用是否影响主线程
UI线程界面渲染/响应点击主线程
TaskPool执行耗时计算不影响
Worker长期后台任务不影响
2. 场景示例
// 主线程(UI线程)
async function onButtonClick() {
  // 1. 显示加载状态(主线程立即执行)
  showLoading();
  
  // 2. 使用TaskPool处理图片(异步)
  const processedImage = await taskpool.execute(
    new taskpool.Task(heavyImageProcess, imageData)
  );
  
  // 3. 更新UI(返回主线程)
  updateImage(processedImage);
}

// 会被放到其他线程执行
@Concurrent 
function heavyImageProcess(data: ArrayBuffer) {
  // 复杂图像处理...
  return processedData;
}

四、常见问题

1: 不是说JS单线程吗?怎么还能多任务?
  • 单线程指:主线程同时只能做一件事
  • 异步秘诀:把耗时操作委托给系统底层(不是JS线程做的)
    • 比如文件读取是操作系统完成的
    • 网络请求是网卡处理的
    • 定时器是系统计时器管理的
2: await是不是让代码变同步了?
  • 不是!这只是语法糖:
// 这两种写法完全等价
async function foo() {
  const a = await bar(); // 看似"暂停"
  console.log(a);
}

function foo() {
  return bar().then(a => {
    console.log(a);
  });
}
3: 为什么动画卡死了?

典型错误:

function doWork() {
  // 长耗时同步操作(阻塞主线程)
  for(let i=0; i<1000000000; i++) {
    heavyCalculation();
  }
  // 期间界面完全冻结
}

正确做法:

async function doWork() {
  // 将任务分片放入任务队列
  for(let i=0; i<100; i++) {
    await taskpool.execute(new taskpool.Task(chunkWork, i));
  }
}

五、加强理解

在浏览器中运行该代码,观察执行顺序:

console.log("开始");

setTimeout(() => console.log("定时器1"), 0);

Promise.resolve().then(() => console.log("微任务1"));

setTimeout(() => console.log("定时器2"), 0);

Promise.resolve().then(() => console.log("微任务2"));

console.log("结束");

/* 输出顺序:
   开始
   结束
   微任务1
   微任务2
   定时器1
   定时器2
*/

总结

  1. 单线程就像快餐店只有1个收银员。
  2. 异步就是让顾客"稍等取餐",不阻塞队伍。
  3. 回调/Promise是取餐时的叫号系统。
  4. 鸿蒙的TaskPool相当于开了后厨专用通道。
  5. 记住黄金法则:主线程只做轻量工作,重活交给其他线程。

鸿蒙开发中 单线程异步模型-优快云博客 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值