沒任務就停止,有任務就依序執行的小功能分享

閱讀時間約 4 分鐘

使用場景

在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。

依序執行不斷產生的任務

依序執行不斷產生的任務


實現過程

打造一個類別(Executor),裡面有一個對外函式(recordData),會把使用者加入的任務不斷加入陣列內。這裡為了方便,讓使用者傳入字串,自動把字串變成過兩秒會印在console的任務函式。

class Executor {
constructor() {
this.pendingFunctionArray = [];
}

recordFunction = async (string) => {
await new Promise((resolve) => setTimeout(resolve, 2000));
console.log(`${string} finish`);
};

recordData = (string) => {
this.pendingFunctionArray.push(() => recordFunction(string));
}
}


加入一個函式,裡面有個回圈會依序執行任務。每次使用者呼叫recordData加入任務,就會呼叫這個函式,讓這個函式不斷執行,直到任務完成後停止。

class Executor {
constructor() {
this.pendingFunctionArray = [];
}

recordFunction = async (string) => {
await new Promise((resolve) => setTimeout(resolve, 2000));
console.log(`${string} finish`);
};

recordData = (string) => {
this.pendingFunctionArray.push(() => recordFunction(string));
this.scheduleTasks();
};

scheduleTasks = async () => {
while (true) {
if (this.pendingFunctionArray.length == 0) break;

const recordFunction = this.pendingFunctionArray.shift();
await recordFunction();
}
};
}


但這樣會產生多個scheduleTasks函式同時執行,可能產生預期外的結果。可以加入一個參數isExecuting來判斷,確保只有一個scheduleTasks函式在執行。

class Executor {
constructor() {
/**@type {Function[]} 待處理陣列 */
this.pendingFunctionArray = [];
/**是否正在排程執行任務 */
this.isExecuting = false;
}

recordFunction = async (string) => {
await new Promise((resolve) => setTimeout(resolve, 2000));
console.log(`${string} finish`);
};

recordData = (string) => {
this.pendingFunctionArray.push(() => recordFunction(string));
this.scheduleTasks();
};

scheduleTasks = async () => {
if (this.isExecuting) return;

this.isExecuting = true;
while (true) {
if (this.pendingFunctionArray.length == 0) {
this.isExecuting = false;
break;
}

const recordFunction = this.pendingFunctionArray.shift();
await recordFunction();
}
};
}


最後附上在線demo的鏈接:依序執行不斷產生的任務

avatar-img
4會員
9內容數
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
s_SoNg的沙龍 的其他內容
ThreeJS ArcballControl呼叫update方法後,視角被翻轉問題的解決記錄
setter和getter能把狀態改變時需做的事情包裝起來,讓外部只需簡單修改參數就能達到預想的效果
在程式任何地方都能修改各種react組件狀態的做法分享
網格擴散可以就像剪紙一樣,把紙上想要的部分剪下來。 通過模型的一個點,找到周圍相鄰的點;其他點又能找到周圍相鄰的點,就像水波一樣擴散出去。 許多3D的算法,如裁切、干涉深度偵測等都會用到。
在THREE r125版本開始,THREE.Geometry就被棄用。 自己的職位是IT前端,由於套件安全性的原因,需要對THREE套件進行升級,但自己所在公司的程式內還有大量的Geometry。 因為前輩們開發了一些複雜強大的算法,如果用Threejs官方建議的正規方法,自己必須要看懂並且改寫算法
ThreeJS ArcballControl呼叫update方法後,視角被翻轉問題的解決記錄
setter和getter能把狀態改變時需做的事情包裝起來,讓外部只需簡單修改參數就能達到預想的效果
在程式任何地方都能修改各種react組件狀態的做法分享
網格擴散可以就像剪紙一樣,把紙上想要的部分剪下來。 通過模型的一個點,找到周圍相鄰的點;其他點又能找到周圍相鄰的點,就像水波一樣擴散出去。 許多3D的算法,如裁切、干涉深度偵測等都會用到。
在THREE r125版本開始,THREE.Geometry就被棄用。 自己的職位是IT前端,由於套件安全性的原因,需要對THREE套件進行升級,但自己所在公司的程式內還有大量的Geometry。 因為前輩們開發了一些複雜強大的算法,如果用Threejs官方建議的正規方法,自己必須要看懂並且改寫算法
你可能也想看
Google News 追蹤