Auto.js学习笔记18:子线程和定时器配合使用(结尾有示例)

目录

threads介绍

threads.start(action):启动一个新线程并执行action。

threads.shutDownAll()

threads.currentThread()

threads.disposable()

threads.lock():新建一个可重入锁

Thread

Thread.interrupt():中断线程运行

Thread.join([timeout]):等待线程执行完成

isAlive():线程是否存活

waitFor():等待线程开始执行

Thread.setTimeout(callback, delay[, ...args])

Thread.setInterval(callback, delay[, ...args])

Thread.clearInterval(id):关闭setInterval子线程定时器

Thread.clearTimeout(id):关闭setTimeout子线程定时器

实际操作:开关子线程实时定时器完整代码

总结


官网文档:Auto.js Pro Docs

threads介绍

threads模块提供了多线程支持,可以启动新线程来运行脚本。

脚本主线程会等待所有子线程执行完成后才停止执行,因此如果子线程中有死循环,请在必要的时候调用exit()来直接停止脚本或threads.shutDownAll()来停止所有子线程。

通过threads.start()启动的所有线程会在脚本被强制停止时自动停止。

由于JavaScript自身没有多线程的支持,因此您可能会遇到意料之外的问题。

threads.start(action):启动一个新线程并执行action。

threads.start(function(){
    //在新线程执行的代码
    while(true){
        log("子线程");
    }
});
while(true){
    log("脚本主线程");
}

threads.shutDownAll()

停止所有通过threads.start()启动的子线程。

threads.currentThread()

返回当前线程。

threads.disposable()

  • ​ 返回 {Disposable}

新建一个Disposable对象,用于等待另一个线程的某个一次性结果。更多信息参见线程通信以及Disposable。 ​

threads.lock():新建一个可重入锁

Thread

线程对象,threads.start()返回的对象,用于获取和控制线程的状态,与其他线程交互等。

Thread对象提供了和timers模块一样的API,例如setTimeout()setInterval()等,用于在该线程执行相应的定时回调,从而使线程之间可以直接交互。

var thread = threads.start(function(){
    //在子线程执行的定时器
    setInterval(function(){
        log("子线程:" + threads.currentThread());
    }, 1000);
});

log("当前线程为主线程:" + threads.currentThread());

//等待子线程启动
thread.waitFor();
//在子线程执行的定时器
thread.setTimeout(function(){
    //这段代码会在子线程执行
    log("当前线程为子线程:" + threads.currentThread());
}, 2000);

sleep(30 * 1000);
thread.interrupt();

Thread.interrupt():中断线程运行

Thread.join([timeout]):等待线程执行完成

如果timeout为0,则会一直等待直至该线程执行完成;否则最多等待timeout毫秒的时间。

var sum = 0;
//启动子线程计算1加到10000
var thread = threads.start(function(){
    for(var i = 0; i < 10000; i++){
        sum += i;
    }
});
//等待该线程完成
thread.join();
toast("sum = " + sum);

isAlive():线程是否存活

返回线程是否存活。如果线程仍未开始或已经结束,返回false; 如果线程已经开始或者正在运行中,返回true

waitFor():等待线程开始执行

调用threads.start()以后线程仍然需要一定时间才能开始执行,因此调用此函数会等待线程开始执行;如果线程已经处于执行状态则立即返回。

var thread = threads.start(function(){
    //do something
});
thread.waitFor();
thread.setTimeout(function(){
    //do something
}, 1000);

Thread.setTimeout(callback, delay[, ...args])

区别在于, 该定时器会在该线程执行。如果当前线程仍未开始执行或已经执行结束,则抛出IllegalStateException

log("当前线程(主线程):" + threads.currentThread());

var thread = threads.start(function(){
    //设置一个空的定时来保持线程的运行状态
    setInterval(function(){}, 1000);
});

sleep(1000);
thread.setTimeout(function(){
    log("当前线程(子线程):" + threads.currentThread());
    exit();
}, 1000);

Thread.setInterval(callback, delay[, ...args])

设置循环执行定时器。

区别在于, 该定时器会在该线程执行。如果当前线程仍未开始执行或已经执行结束,则抛出IllegalStateException

Thread.clearInterval(id):关闭setInterval子线程定时器

Thread.clearTimeout(id):关闭setTimeout子线程定时器

实际操作:开关子线程实时定时器完整代码

isEmpty、getSameDayCustomGetTime都是自己封装的函数

state:true是开启,false是关闭

function mainTimerModular(state){
   var startSuccessState = false;
   if(state){
        mainTimerThread =  threads.start(function(){
            toast("主计时器线程模块开启成功");
            let time = wxAutoConfigObj.timingTime;
            let h = time.substring(0,time.lastIndexOf(":"));
            let m = time.substring(time.indexOf(":")+1);
            let setTime = myUtils.getSameDayCustomGetTime(h,m);
            //在新线程执行的代码
            mainIntervalId = setInterval(function(){
                var curTime = new Date().getTime() ;
                if((setTime+1000) > curTime && curTime >= setTime){
                    log("触发成功");
                    startSuccessState = true;
                }else if((setTime+3000) > curTime && curTime>setTime && !startSuccessState){
                    startSuccessState = true;//强行触发,该情况一般不会出现
                    toastLog("时间到了没触发");
                }else if(curTime>(setTime+3000)){//当前时间小于最迟的范围值
                    if(startSuccessState){  
                        startSuccessState = false;
                        log("复原启动状态");
                    }
                }
            }, 1000);
        }); 
   }else{
        //停止线程执行
        if(!myUtils.isEmpty(mainIntervalId)){
            clearInterval(mainIntervalId);
        }
        if(!myUtils.isEmpty(mainTimerThread)){
            mainTimerThread.interrupt();
            mainTimerThread = null;
        }
        toast("主计时器线程模块关闭!")
   }  
}

总结

开发中,有很多地方会用到子线程和定时器要多练习。

光看不敲是没用的
看后一定要去实践
一定要去敲代码
一定要去运行试错
这样才是有意义的学习

猜你喜欢

转载自blog.csdn.net/piyangbo/article/details/125907351