HarmonyOS鸿蒙Next中Sendable如何使用Lambda表达式

HarmonyOS鸿蒙Next中Sendable如何使用Lambda表达式 有一个类如:

class A{
  num:number=0
  runnable:()=>void=()=>{
    this.num++
  }
  cal(){
    if(num<10){
      setTimeout(this.runnable,100)
    }else{
      this.num--
    }
  }
}

如果想将其在多线程中执行,就需要使用Sendable协议,但是使用Sendable协议的话,需要将数据类型变为Sendable支持的类型,而lambda表达式()=>void是不支持的,我应该如何修改呢?注意,上述代码只是个最小示例,并不是说我要改上面的类,所以请不要回复类似:

@Sendable
class A{
  num:number=0
  cal(){
    if(num<10){
      setTimeout(this.num++,100)
    }else{
      this.num--
    }
  }
}

这样的修改,实际我是需要Lambda表达式()=>void能够在Sendable中使用的办法


更多关于HarmonyOS鸿蒙Next中Sendable如何使用Lambda表达式的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

开发者您好,Sendable使用规则与约束有继承规则接口实现规则,Sendable类/接口成员变量规则,泛型规则,类型转换规则,函数规则等,具体参考Sendable使用规则与约束

箭头函数不支持@Sendable装饰器,因此它是非Sendable函数,因此不支持共享。正例如下:

[@Sendable](/user/Sendable)
type SendableFuncType = () => void;

[@Sendable](/user/Sendable)
function SendableFunc() {
  console.info("Sendable func");
}

[@Sendable](/user/Sendable)
class SendableClass {
  constructor(f: SendableFuncType) {
    this.func = f;
  }
  func: SendableFuncType;
}

let sendableClass = new SendableClass(SendableFunc);

更多关于HarmonyOS鸿蒙Next中Sendable如何使用Lambda表达式的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,Sendable接口用于跨线程安全传输数据。Lambda表达式可通过Sendable接口实现,确保闭包捕获的数据符合Sendable要求。示例:使用Sendable标记Lambda,如let task: @Sendable () -> Void = { ... }。这允许Lambda在并发域中安全传递,系统会自动验证捕获的变量是否线程安全。需注意避免在Lambda中捕获非Sendable对象。

在HarmonyOS Next中,Sendable协议要求跨线程传递的数据必须是可序列化的。Lambda表达式(()=>void)本身不是Sendable类型,但可以通过以下方式解决:

  1. 使用Sendable闭包包装Lambda:
@Sendable
class SendableClosure {
  private action: () => void;
  
  constructor(action: () => void) {
    this.action = action;
  }
  
  execute(): void {
    this.action();
  }
}
  1. 在Sendable类中使用Sendable闭包:
@Sendable
class A {
  num: number = 0;
  runnable: SendableClosure = new SendableClosure(() => {
    // 注意:这里不能直接访问this.num
    // 需要通过参数传递数据
  });
  
  cal() {
    if (this.num < 10) {
      const closure = new SendableClosure(() => {
        // 通过闭包参数传递所需数据
      });
      setTimeout(closure.execute.bind(closure), 100);
    } else {
      this.num--;
    }
  }
}

关键点:

  • Sendable闭包内部不能直接访问外部类的非Sendable属性
  • 需要通过参数传递所需数据
  • 使用bind方法确保执行上下文正确

这样既保持了Lambda表达式的灵活性,又满足了Sendable的线程安全要求。

回到顶部