摘要:而這樣一層一層嵌套進(jìn)去的作用就是一個執(zhí)行完了,執(zhí)行下一個。函數(shù)的參數(shù)和函數(shù)一樣,只不過是執(zhí)行的順序與函數(shù)相反,是倒過來執(zhí)行的。第二個方案,也是他給我的思路。
這篇文章的起源是這樣一段代碼
這段代碼的作用很簡單,就是讓一系列的動畫,按順序執(zhí)行。而這樣一層一層嵌套進(jìn)去的作用就是一個執(zhí)行完了,執(zhí)行下一個。
為了解決這個問題我就想到了是不是可以把這些事件放到一個數(shù)組里,然后依次執(zhí)行呢?也就是說實現(xiàn)一個seq(tasks,finally)函數(shù)
/** * @param {function []} tasks - function array * @param {function} cb - 執(zhí)行完的回調(diào) */ function seq(tasks, cb) { }
我的思路是每次執(zhí)行完一個function之后再執(zhí)行下一個函數(shù),如果執(zhí)行到最后一個函數(shù)就執(zhí)行最后的cb即
function seq(tasks, cb) { (function runTask(i) { var task = tasks[i]; task(function() { i++; if (i !== tasks.length) { runTask(i); } else { cb(); } }); })(0); }
但是顯然這么實現(xiàn)并不優(yōu)雅(Zhuāng Bī),那么有沒有更優(yōu)雅的方案呢?顯然是有的。我們可以使用ES5的reduceRight函數(shù)(MSDN文檔)
如果你并不知道這個函數(shù)的話,我們就要從和它差不多的reduce函數(shù)(MSDN文檔)說起了。
reduce函數(shù)接收兩個參數(shù)callback、initialValue
callback
執(zhí)行數(shù)組中每個值的函數(shù),包含四個參數(shù)
previousValue
上一次調(diào)用回調(diào)返回的值,或者是提供的初始值(initialValue)
currentValue
數(shù)組中當(dāng)前被處理的元素
index
當(dāng)前元素在數(shù)組中的索引
array
調(diào)用 reduce 的數(shù)組
initialValue
作為第一次調(diào)用 callback 的第一個參數(shù)。
/** @examples **/ var array = [ { id: 1, name: "小李" }, { id: 2, name: "小張" }, { id: 3, name: "小劉" }, { id: 4, name: "小王" } ] var objMap = array.reduce(function(map,nowObj,index,array) { map[nowObj.id] = nowObj; return map; },{});
很簡單的就把一個array,轉(zhuǎn)成了一個以id為key,obj為value的ObjMap有木有?就是這么簡單。
reduceRight函數(shù)的參數(shù)和reduce函數(shù)一樣,只不過是執(zhí)行的順序與reduce函數(shù)相反,是倒過來執(zhí)行的。這樣的話我們就可以把上面那個tasks轉(zhuǎn)換成類似最一開始那張圖一樣的結(jié)構(gòu)。
function seq2(tasks, cb) { tasks.reduceRight(function(cb, task) { return function() { return task(cb); }; }, cb)(); } //這段代碼的推導(dǎo)如下 //第一次執(zhí)行 function() { return task5(cb); }; //第二次執(zhí)行 function() { return task4(function() { return task5(cb); }); } //第三次執(zhí)行 function() { return task3(function() { return task4(function() { return task5(cb); }); }); }; //第四次執(zhí)行 function() { return task2(function() { return task3(function() { return task4(function() { return task5(cb); }); }); }) }; //最后一次執(zhí)行 function() { return task1(function() { return task2(function() { return task3(function() { return task4(function() { return task5(cb); }); }); }); }); };
這樣就得到了一個跟上面最一開始那張圖一模一樣的一個function,然后最重要的是reduceRight面那個(),他就是啟動這個最終返回function的開關(guān)。
測試用例如下:
var tasks = [1, 2, 3, 4, 5]; tasks = tasks.map(function(i) { return function(cb) { setTimeout(function() { console.log(i); cb(); }, Math.random() * 500 | 0); } }); seq(tasks, function() { console.log("all Done"); }); seq2(tasks, function() { console.log("all Done"); });
這個問題是我公司的一位同事(老師)給我出的題目。第二個方案,也是他給我的思路。感謝我的這位老師,雖然在工作中我說的不多,但是在我內(nèi)心里,我對您的崇拜那是簡直了。哈哈。最后是github源代碼
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/79611.html
摘要:并行和串行任務(wù)在里面異步是一個很重要的知識點的異步跟其他語言不一樣他是根據(jù)執(zhí)行回調(diào)的方式來實現(xiàn)的。在之前,執(zhí)行任務(wù)想要實現(xiàn)這個流程控制只能通過依賴來實現(xiàn)或者通過而在之后官方自己實現(xiàn)了和來實現(xiàn)。 JavaScript 并行和串行任務(wù) 在 JavaScript 里面 異步 是一個很重要的知識點,JS 的異步跟其他語言不一樣, 他是根據(jù)執(zhí)行回調(diào)的方式來 實現(xiàn)的。由于我們不知道異步什么時候會...
摘要:相關(guān)環(huán)境由于是一個幾年前的項目,所以使用的是這樣的。一些小提示本次優(yōu)化筆記,并不會有什么文件的展示。將異步改為了串行,喪失了作為異步事件流的優(yōu)勢。 這兩天針對一個Node項目進(jìn)行了一波代碼層面的優(yōu)化,從響應(yīng)時間上看,是一次很顯著的提升。 一個純粹給客戶端提供接口的服務(wù),沒有涉及到頁面渲染相關(guān)。 背景 首先這個項目是一個幾年前的項目了,期間一直在新增需求,導(dǎo)致代碼邏輯變得也比較復(fù)雜,接...
摘要:所以這里需要另外的操作來對文件加載進(jìn)行優(yōu)化加載這是中定義的一個屬性,它用來表示的是,當(dāng)渲染引擎遇到的時候,如果引用的是外部資源,則會暫時掛起,并進(jìn)行加載。 在js引擎部分,我們可以了解到,當(dāng)渲染引擎解析到script標(biāo)簽時,會將控制權(quán)給JS引擎,如果script加載的是外部資源,則需要等待下載完后才能執(zhí)行。 所以,在這里,我們可以對其進(jìn)行很多優(yōu)化工作。 放置在body底部 為了讓渲染引...
摘要:回調(diào)函數(shù)指定了下一步操作。異步操作的流程控制參數(shù)為秒后返回結(jié)果上面代碼的函數(shù)是一個異步任務(wù),非常耗時,每次執(zhí)行需要秒才能完成,然后再調(diào)用回調(diào)函數(shù)。 單線程模型同步任務(wù)和異步任務(wù)任務(wù)隊列和事件循環(huán)異步操作的模式回調(diào)函數(shù)事件監(jiān)聽發(fā)布/訂閱異步操作的流程控制串行執(zhí)行并行執(zhí)行并行與串行的結(jié)合 1.單線程模型指的是js只在線程運行,一個時間執(zhí)行一個任務(wù),其他任務(wù)排隊。事實上是一個運行腳本的主線程...
摘要:前同事留下的測試,是基于瀏覽器的,主要還是功能測試。這里不詳細(xì)說怎么在瀏覽器端使用測試了。而且作者也是建議和支持這樣做的,簡單明了的測試腳本,重要性有時候可能和測試本身一樣重要。經(jīng)測試,在瀏覽器也有這種問題。 2016-09-03 更新 隨著在工作學(xué)習(xí)中更多地接觸、使用測試工具,發(fā)現(xiàn)自己在本文中的一些記錄是不準(zhǔn)確、不正確的。 今天(九月三日)在家看了 NingJs 的直播,其中有一個分...
閱讀 1245·2021-11-22 13:54
閱讀 1433·2021-11-22 09:34
閱讀 2705·2021-11-22 09:34
閱讀 4020·2021-10-13 09:39
閱讀 3348·2019-08-26 11:52
閱讀 3369·2019-08-26 11:50
閱讀 1537·2019-08-26 10:56
閱讀 1919·2019-08-26 10:44