react-native實現定時任務

react-native中有時候須要定時執行一些後臺任務,好比定時發送消息,定時統計數據等.這個時候就須要使用另外註冊一個視圖來作這些東西了,否則在同步任務中作這些任務,一旦任務比較耗時就會卡住後面的進程,甚至致使後面的進程再也不渲染頁面.javascript

註冊另一個入口

在合適的位置:頁面啓動或者某個須要的時候,註冊並啓動咱們的另一個視圖.這個時候其實至關於啓動了另一個線程.java

這裏注意一下,這個視圖裏的東西千萬不要直接刷新UI相關的數據,全部的內容都應該是內存相關的.react

AppRegistry.registerRunnable('RunableTask', TaskRun)

AppRegistry.runApplication('RunableTask', {});

啓動定時器

調用init方法,啓動咱們本身的定時器刷新方法,這裏我暫時定義1秒刷新一次,低於1秒間隔的定時器將不在執行.這裏也是爲了防止部分人設置低間隔的定時器致使APP崩潰.react-native

這裏使用react-native內部提供的requestAnimationFrame方法,每次刷新的時候先判斷一次是否能夠執行任務.app

const tasks = new Map();
let currDate = Date.now();
/**
 * 初始化
 */
exports.init = function () {
    global.requestAnimationFrame(run);
}
/**
 * 執行,每秒執行一次
 * 保證秒級工做正確
 */
function run() {
    const now = Date.now();
    if (now > currDate + 1000) {
        currDate = now;
        tasks.forEach(item => item.preStart(now));
    }
    global.requestAnimationFrame(run);
}

任務基類

全部的任務都須要繼承這個基類,定時器運行的時候也會經過基類內部的方法去判斷是否須要執行方法.這裏對外實現了一個timer是時間間隔,單位是毫秒,還有一個start方法用來給每一個任務使用的.函數

經過每次執行preStart方法判斷下次執行的時間到了沒有來決定是否執行自定義方法.若是到了同時還要計算下一次的時間並存好.測試

/**
 * 基礎工做類
 */
class Jobs {
    name = "base";
    /**
     * 下次執行時間戳
     */
    nextTime = 0;
    /**
     * 重載:時間間隔
     */
    timer = 0;
    /**
     * 預啓動
     */
    preStart(now) {
        if (this.timer < 1000) return;
        if (this.nextTime > now) return;
        if (this.nextTime === 0) return this.nextTime = now + this.timer;
        this.nextTime += this.timer;
        this.start(now);
    }
    /**
     * 重載:執行一次設置的方法
     */
    start() { }
}

實現並加入

將設置好的任務加入全局的map示例中,運行的時候會從這個示例中取須要的任務出來.this

/**
 * 添加一個工做
 * @param {*} name  名稱
 * @param {*} time  時間
 * @param {*} fn    執行函數
 */
const addJob = (name, Job) => tasks.set(name, new Job())

exports.addJob = addJob;

/**
 * 取消任務
 * @param {*} name 
 */
const cancelJob = name => tasks.delete(name);

exports.cancelJob = cancelJob;

測試任務

這裏模擬一次定時發送統計消息.url

另一個地方實現了將每次須要發送的消息存入內存中,這裏只負責取出須要發送的消息.線程

設置3秒執行一次發送任務,若是數量比較少就修改定時任務的間隔,後面的任務延遲發送.

若是後臺接收一次大量的數據,也能夠將屢次統計合併爲一次統計,請求的個數會更少一些.

/**
 * 定時觸發統計方法
 */
class TrackJob extends Jobs {
    timer = 3000;
    start() {
        let list = TackList();
        if (list.length > 10) {
            this.timer = 3000;
        } else {
            this.timer = 5000;
        }
        list.forEach(item => {
            request.trackData(item.url, item.data);
            log("埋點事件", item.data);
        })
    }
}
addJob("Track", TrackJob);

更多擴展

在目前的基礎上擴展時間間隔的設定方式,實現固定時間日期執行任務.這裏可能須要app一直活着才能保證.

加入執行次數,執行超過必定的此時就再也不執行.

文章地址

相關文章
相關標籤/搜索