數組的遍歷你都會用了,那Promise版本的呢
原文:https://segmentfault.com/a/1190000014598785
這裡指的遍歷方法包括: 、 、 、 、 、 、 因為最近要進行了一些數據匯總, 版本已經是8.11.1了,所以直接寫了個 的腳本。 但是在對數組進行一些遍歷操作時,發現有些遍歷方法對 的反饋並不是我們想要的結果。
當然,有些嚴格來講並不能算是遍歷,比如說 , 這些的。 但確實,這些都會根據我們數組的元素來進行多次的調用傳入的回調。
這些方法都是比較常見的,但是當你的回調函數是一個 時,一切都變了。
前言
為 的語法糖 文中會直接使用 替換
map
可以說是對 最友好的一個函數了。 我們都知道, 接收兩個參數:
對每項元素執行的回調,回調結果的返回值將作為該數組中相應下標的元素
一個可選的回調函數 指向的參數
上邊是一個普通的 執行,但是當我們的一些計算操作變為非同步的:
這時候,我們獲取到的返回值其實就是一個由 函數組成的數組了。
所以為什麼上邊說 函數為最友好的,因為我們知道, 有一個函數為 會將一個由 組成的數組依次執行,並返回一個 對象,該對象的結果為數組產生的結果集。
首先使用 對數組進行包裝,然後用 獲取結果。
reduce/reduceRight
的函數簽名想必大家也很熟悉了,接收兩個參數:
對每一項元素執行的回調函數,返回值將被累加到下次函數調用中,回調函數的簽名:
累加的值
當前正在處理的元素
當前正在處理的元素下標
調用 的數組
可選的初始化的值,將作為 的初始值
這個代碼也是沒毛病的,同樣如果我們加和的操作也是個非同步的:
這個結果返回的就會很詭異了,我們在回看上邊的 的函數簽名
對每一項元素執行的回調函數,返回值將被累加到下次函數調用中
然後我們再來看代碼, 這個在最開始也提到了,是 的語法糖,為了看得更清晰,我們可以這樣寫:
也就是說,我們 的回調函數返回值其實就是一個 對象 然後我們對 對象進行 操作,得到那樣怪異的返回值也就很合情合理了。
當然, 的調整也是很輕鬆的:
我們對 調用 ,然後再與當前 進行加和,在最後我們的 返回值也一定是一個 ,所以我們在最外邊也添加 的字樣 也就是說我們每次 都會返回一個新的 對象,在對象內部都會獲取上次 的結果。 我們調用 實際上得到的是類似這樣的一個 對象:
reduceRight
這個就沒什麼好說的了。。跟 只是執行順序相反而已
forEach
,這個應該是用得最多的遍歷方法了,對應的函數簽名:
,對每一個元素進行調用的函數
,當前元素
,當前元素下標
,調用 的數組引用
,一個可選的回調函數 指向
我們有如下的操作:
普通版本我們是可以直接這麼輸出的,但是如果遇到了
並不關心回調函數的返回值,所以 只是執行了三個會返回 的函數 所以如果我們想要得到想要的效果,只能夠自己進行增強對象屬性了:
會忽略非 值, 、 與普通代碼無異
filter
作為一個篩選數組用的函數,同樣具有遍歷的功能: 函數簽名同 ,但是 返回值為 的元素將被放到 函數返回值中去。
我們要進行一個奇數的篩選,所以我們這麼寫:
然後我們改為 版本:
這會導致我們的篩選功能失效,因為 的返回值匹配不是完全相等的匹配,只要是返回值能轉換為 ,就會被認定為通過篩選。 對象必然是 的,所以篩選失效。 所以我們的處理方式與上邊的 類似,同樣需要自己進行對象增強 但我們這裡直接選擇一個取巧的方式:
我們可以直接在內部調用 方法,因為我們知道 會將所有的返回值返回為一個新的數組。 這也就意味著,我們 可以拿到我們對所有 進行篩選的結果, 或者 。 接下來對原數組每一項進行返回對應下標的結果即可。
some
作為一個用來檢測數組是否滿足一些條件的函數存在,同樣是可以用作遍歷的 函數簽名同 ,有區別的是當任一 返回值匹配為 則會直接返回 ,如果所有的 匹配均為 ,則返回
我們要判斷數組中是否有元素等於 :
然後我們將它改為
這個函數依然會返回 ,但是卻不是我們想要的,因為這個是 返回的 對象被認定為 。
所以,我們要進行如下處理:
因為 在匹配到第一個 之後就會終止遍歷,所以我們在這裡邊使用 的話是在性能上的一種浪費。 同樣是利用了 會忽略普通表達式的優勢,在內部使用 來實現我們的需求
every
以及我們最後的一個 函數簽名同樣與 一樣, 但是 的處理還是有一些區別的: 其實換一種角度考慮, 就是一個反向的 會在獲取到第一個 時終止 而 會在獲取到第一個 時終止,如果所有元素均為 ,則返回
我們要判定數組中元素是否全部大於3
很顯然,一個都沒有匹配到的,而且回調函數在執行到第一次時就已經終止了,不會繼續執行下去。 我們改為 版本:
這個必然是 ,因為我們判斷的是 對象 所以我們拿上邊的 實現稍微修改一下:
當匹配到任意一個 時,直接返回 ,終止遍歷。
後記
關於數組的這幾個遍歷方法。 因為 和 的特性,所以是在使用 時改動最小的函數。的結果很像一個洋蔥模型但對於其他的遍歷函數來說,目前來看就需要自己來實現了。
四個 函數的實現:https://github.com/Jiasm/notebook/tree/master/array-sync
參考資料
Array - JavaScript | MDN
END
TAG:JavaScript |