国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

JavaScript隊列函數和異步執行詳解

2024-05-06 15:15:44
字體:
來源:轉載
供稿:網友

編輯注:在Review別人的JavaScript代碼時曾看到過類似的隊列函數,不太理解,原來這個是為了保證函數按順序調用。讀了這篇文章之后,發現還可以用在異步執行等。

假設你有幾個函數fn1、fn2和fn3需要按順序調用,最簡單的方式當然是:

fn1();fn2();fn3();

但有時候這些函數是運行時一個個添加進來的,調用的時候并不知道都有些什么函數;這個時候可以預先定義一個數組,添加函數的時候把函數push 進去,需要的時候從數組中按順序一個個取出來,依次調用:

var stack = [];// 執行其他操作,定義fn1stack.push(fn1);// 執行其他操作,定義fn2、fn3stack.push(fn2, fn3);// 調用的時候stack.forEach(function(fn) { fn() });

 這樣函數有沒名字也不重要,直接把匿名函數傳進去也可以。來測試一下:

var stack = [];function fn1() {  console.log('第一個調用');}stack.push(fn1);function fn2() {  console.log('第二個調用');}stack.push(fn2, function() { console.log('第三個調用') });stack.forEach(function(fn) { fn() }); // 按順序輸出'第一個調用'、'第二個調用'、'第三個調用'

這個實現目前為止工作正常,但我們忽略了一個情況,就是異步函數的調用。異步是JavaScript 中無法避免的一個話題,這里不打算探討JavaScript 中有關異步的各種術語和概念,請讀者自行查閱(例如某篇著名的評注)。如果你知道下面代碼會輸出1、3、2,那請繼續往下看:

console.log(1);setTimeout(function() {  console.log(2);}, 0);console.log(3);

假如stack 隊列中有某個函數是類似的異步函數,我們的實現就亂套了:

var stack = [];function fn1() { console.log('第一個調用') };stack.push(fn1);function fn2() {  setTimeout(function fn2Timeout() {     console.log('第二個調用');  }, 0);}stack.push(fn2, function() { console.log('第三個調用') });stack.forEach(function(fn) { fn() }); // 輸出'第一個調用'、'第三個調用'、'第二個調用'

 問題很明顯,fn2確實按順序調用了,但setTimeout里的function fn2Timeout() { console.log(‘第二個調用') }卻不是立即執行的(即使把timeout 設為0);fn2調用之后馬上返回,接著執行fn3,fn3執行完了然才真正輪到fn2Timeout。

怎么解決?我們分析下,這里的關鍵在于fn2Timeout,我們必須等到它真正執行完才調用fn3,理想情況下大概像這樣:

function fn2() {  setTimeout(function() {    fn2Timeout();    fn3();  }, 0);}

但這樣做相當于把原來的fn2Timeout整個拿掉換成一個新函數,再把原來的fn2Timeout和fn3插進去。這種動態改掉原函數的寫法有個專門的名詞叫Monkey Patch。按我們程序員的口頭禪:“做肯定是能做”,但寫起來有點擰巴,而且容易把自己繞進去。有沒更好的做法?

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 齐齐哈尔市| 阿克陶县| 安龙县| 平顺县| 南乐县| 兖州市| 昌宁县| 灌阳县| 兰州市| 晋城| 扎鲁特旗| 姚安县| 定日县| 北川| 巧家县| 枣强县| 普安县| 留坝县| 金溪县| 赤城县| 襄城县| 枣强县| 铜川市| 石狮市| 海安县| 渝中区| 颍上县| 安庆市| 绵竹市| 南丹县| 肥乡县| 陇西县| 蕲春县| 南康市| 方正县| 涞水县| 即墨市| 长阳| 临汾市| 思南县| 孝感市|