HarmonyOS鸿蒙Next中请教下用while的方式实现每隔200毫秒调用方法
HarmonyOS鸿蒙Next中请教下用while的方式实现每隔200毫秒调用方法
请教下如何用while(true)的方式,在页面调用方法,类似java开启个线程,在线程方法中每隔200毫秒响一下
isRunning : Boolean = true
async text() {
let preTime : number = Date.now()
while (this.isRunning){
try {
let currentTime : number = Date.now()
if (currentTime - preTime == 500) {
console.log('jiejie', '====='+(currentTime-preTime) + " ==" + Date.now())
preTime = currentTime
// 自己的方法
}
} catch (e) {
}
}
}
如果像上面写,运行几秒直接死了。然后我找了TaskPool好像可以实现,又换个写法
@Builder
customBottomImg(){
Row(){
Image($r('app.media.speed')).width(40)
Image($r('app.media.gray_checkbox_play')).width(100).margin({left :40,right :40})
.onClick(() =>{
this.startTask()
})
Image($r('app.media.music')).width(40)
.onClick(() =>{
})
}.margin({top :100})
}
// 这个方法写在page里面
startTask() {
const task = new taskpool.Task(startTestTask);
taskpool.execute(task).then(() => {
console.info('jiejie: execute task success!');
})
}
@Concurrent
function startTestTask(){
let preTime : number = Date.now()
while (true){
try {
let currentTime : number = Date.now()
if (currentTime - preTime == 500) {
console.log('jiejie', '====='+(currentTime-preTime) + " ==" + Date.now())
preTime = currentTime
}
} catch (e) {
}
}
}
这样确实能实现每隔500毫秒调用一下了,那我怎么停止?怎么在方法里面调用界面page的自己实现的方法。
或者有其他更好的方法,能实现每隔500毫秒调用一下函数。倒计时setInterval方式不行
更多关于HarmonyOS鸿蒙Next中请教下用while的方式实现每隔200毫秒调用方法的实战教程也可以访问 https://www.itying.com/category-93-b0.html
import { taskpool } from '@kit.ArkTS';
@Component
struct TestPage {
@State currentPosition : number = 0
private taskPromise: Promise<Object> | undefined;
build() {
Column({space : 20}) {
Button('测试开始倒计时')
.onClick(() => {
this.startTaskLoop()
}).margin({top:40})
Button('停止倒计时')
.onClick(() => {
this.stopTaskLoop()
})
Text(this.currentPosition.toString()).fontSize(50).fontColor(Color.Red)
}
}
startTaskLoop() {
runningFlag[0] = 1
const currentTask = new taskpool.LongTask(startTestTask,sharedIntArray, 500)
currentTask.onReceiveData(this.receiveData.bind(this))
this.taskPromise = taskpool.execute(currentTask)
}
stopTaskLoop() {
runningFlag[0] = 0
this.taskPromise?.then(() => {
console.log('jiejie',"任务完成处理")
})
}
receiveData(position: number): void { // 接受回调
this.currentPosition = position
}
}
// 定义共享对象
const sharedIntArray : SharedArrayBuffer= new SharedArrayBuffer(4);
const runningFlag : Int32Array = new Int32Array(sharedIntArray);
@Concurrent //实现任务的函数需要使用装饰器@Concurrent标注
function startTestTask(sharedBuffer: SharedArrayBuffer,interval: number) {
const runningFlag = new Int32Array(sharedBuffer);
let preTime = Date.now() - interval;
let position : number = 0
while (Atomics.load(runningFlag, 0) === 1) {
const currentTime = Date.now();
if (currentTime - preTime >= interval) {
taskpool.Task.sendData(position);
preTime = currentTime;
position++
}
}
}
使用TaskPool+共享内存控制
// 在Page中定义
@State isRunning: boolean = true;
private taskPromise: Promise<Object> | null = null;
startTask() {
const sharedIntArray = new SharedArrayBuffer(4);
const runningFlag = new Int32Array(sharedIntArray);
runningFlag = 1;
const task = new taskpool.Task(startTestTask, sharedIntArray);
this.taskPromise = taskpool.execute(task);
}
stopTask() {
this.isRunning = false;
this.taskPromise?.then(() => {/* 任务完成处理 */});
}
@Concurrent
function startTestTask(sharedBuffer: SharedArrayBuffer) {
const runningFlag = new Int32Array(sharedBuffer);
let preTime = Date.now();
while (Atomics.load(runningFlag, 0) === 1) {
const currentTime = Date.now();
if (currentTime - preTime >= 500) {
// 通过Emitter通知UI线程
emitter.emit('timerTick', { timestamp: currentTime });
preTime = currentTime;
}
}
}
有没有试过使用setTimeout封装个sleep方法
async function sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html
isRunning : Boolean = true
async startText() { let preTime : number = Date.now() while (this.isRunning){ let currentTime : number = Date.now() if (currentTime - preTime >= 500) { console.log(‘jiejie’,’=====’+(currentTime-preTime)+" ==" + Date.now()) preTime = currentTime } await sleep(1) } }
async function sleep(ms: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); } 是这个意思吗???
直接用setInterval
用setInterval不是有毫秒误差吗,
把下面html内容转换成Markdown格式,要求:
- 转换的时候需要去掉复制和深色代码主题
- 输出的内容不显示“基本信息”
- html代码中有图片需要转换成markdown格式
- html代码中没有图片请不要加上图片
- html中img标签的地址为空的话不输出,不转换
- 输出内容的时候不需要解释,不需要建议
- 只需要输出转换完毕的Markdown文档,不需要输出其他内容
- 内容中没有图片或者图片为空的话不要加图片
- 不要在内容中加https://example.com/image.jpg这样的图片
内容如下:或者你递归调用,递归的时候使用promise,不然会栈溢出,
很喜欢HarmonyOS的卡片式设计,信息一目了然,操作也更便捷。
你这也太精确了吧,一定要等于500毫秒,Java也不能这么写的,cpu会满的。你可以用setInterval
每50毫秒一次,判断大于500毫秒,
java我就用ExecutorService在线程中这么写,没问题。这个500毫秒不是固定的。用setInterva我试过有误差。
手机不是服务器,不可能让你无限制用cpu的,你这么写就不会释放cpu。
在HarmonyOS Next中,使用while循环实现定时调用需结合异步任务处理。示例代码如下(ArkTS):
import { BusinessError } from '@ohos.base';
async function delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function periodicTask() {
while (true) {
await delay(200);
yourMethod(); // 替换为实际调用的方法
}
}
// 启动任务
periodicTask().catch((err: BusinessError) => {
console.error(\`Task failed: \${err.code}, \${err.message}\`);
});
注意:这种方式会阻塞当前任务,建议在后台线程执行。
在HarmonyOS Next中实现定时任务,建议使用TaskPool结合Promise的方式。以下是改进方案:
- 使用TaskPool实现可控的定时循环:
let shouldStop = false;
@Concurrent
async function intervalTask(interval: number) {
while(!shouldStop) {
const startTime = Date.now();
// 执行你的业务逻辑
const elapsed = Date.now() - startTime;
const remaining = interval - elapsed;
if (remaining > 0) {
await new Promise(resolve => setTimeout(resolve, remaining));
}
}
}
// 启动任务
function startInterval() {
shouldStop = false;
const task = new taskpool.Task(intervalTask, 200);
taskpool.execute(task);
}
// 停止任务
function stopInterval() {
shouldStop = true;
}
- 如果需要更新UI,可以通过Emitter发送事件:
import emitter from '@ohos.events.emitter';
// 在任务中发送事件
emitter.emit({
eventId: 1 // 自定义事件ID
});
// 在UI组件中监听
emitter.on(1, () => {
// 更新UI
});
- 更推荐使用Worker实现长时间运行的定时任务:
// 创建Worker
const worker = new worker.ThreadWorker('entry/ets/workers/MyWorker.ts');
// Worker中实现定时逻辑
postMessage('init');
setInterval(() => {
postMessage('tick');
}, 200);
// 主线程监听
worker.onmessage = (e) => {
if (e.data === 'tick') {
// 处理定时逻辑
}
};
这种方法相比while循环更节省资源,且不会阻塞主线程。