激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

node.js|vue.js|jquery|angularjs|React|json|js教程|

香港云服务器
服務(wù)器之家 - 編程語(yǔ)言 - JavaScript - node.js - Nodejs 數(shù)組的隊(duì)列以及forEach的應(yīng)用詳解

Nodejs 數(shù)組的隊(duì)列以及forEach的應(yīng)用詳解

2022-01-24 16:38WificamSDK7 node.js

這篇文章主要介紹了Nodejs 數(shù)組的隊(duì)列以及forEach的應(yīng)用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

本文主要記錄了在Nodejs開(kāi)發(fā)過(guò)程中遇到過(guò)的由數(shù)組特性引起的問(wèn)題及解決方式,以及對(duì)數(shù)組的靈活應(yīng)用。

本文代碼測(cè)試結(jié)果均基于node v6.9.5

數(shù)組與隊(duì)列

利用數(shù)組對(duì)象方法push/shift可實(shí)現(xiàn)隊(duì)列先進(jìn)先出特性,例如:

?
1
2
3
4
5
6
7
8
9
10
11
12
>a=[]
[]
>a.push(2.3.4)
3
>a.push(2)
3
>a
[2.3.4.2]
>a.shift()
2
>a
>[3.4.2]

數(shù)組與forEach

對(duì)數(shù)組的刪除操作有兩種常見(jiàn)方式:delete和使用splice方法,需要明確他們的區(qū)別。

操作/方法 說(shuō)明
splice 刪除并返回指定的數(shù)組元素,數(shù)組本身長(zhǎng)度會(huì)改變;但不會(huì)free元素對(duì)象
delete 刪除(free)元素對(duì)象,數(shù)組元素不變,值變?yōu)閡ndefined

如果要從數(shù)組中徹底刪除某個(gè)元素,使用splice即可:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
> a=[1,2,3]
[ 1, 2, 3 ]
> a.splice(1,1)
[ 2 ]
> a
[ 1, 3 ]
> a.length
2
> a.forEach(function(item, index){console.info("index[", index,"]:", item)});
index[ 0 ]: 1
index[ 1 ]: 3
undefined
>

那么,當(dāng)使用delete刪除某個(gè)元素對(duì)象后,此時(shí)執(zhí)行forEach的效果是什么?

forEach對(duì)含空元素?cái)?shù)組處理機(jī)制

測(cè)試結(jié)果如下

?
1
2
3
4
5
6
7
8
9
10
11
12
> a=[1,2,3]
[ 1, 2, 3 ]
> delete a[1]
true
> a
[ 1, , 3 ]
> a.length
3
> a.forEach(function(item, index){console.info("index[", index,"]:", item)});
index[ 0 ]: 1
index[ 2 ]: 3
undefined

從測(cè)試結(jié)果來(lái)看,forEach并不會(huì)遍歷到值為undefined的哪一項(xiàng)。這在實(shí)際應(yīng)用中如何判斷forEach是否結(jié)束是一大挑戰(zhàn)。

解決配合forEach的異步特性應(yīng)用,可為數(shù)組添加prototype來(lái)自行管理設(shè)置有效數(shù)據(jù);

效果如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> a=[1,2,3]
[ 1, 2, 3 ]
> a.validnum=3
3
> delete a[2]
true
> a.validnum=2
2
> a
[ 1, 2, , validnum: 2 ]
> a.length
3
> a.validnum
2
> a.forEach(function(item, index){console.info("index[", index,"]:", item)});
index[ 0 ]: 1
index[ 1 ]: 2
undefined
>

補(bǔ)充:Node.js 數(shù)組 forEach 同步處理上下文語(yǔ)句

習(xí)慣了C語(yǔ)言系的思維方式,剛接觸Node.js,它的異步處理讓我頭大。

寫(xiě)代碼遇到這么一個(gè)場(chǎng)景,需要循環(huán)對(duì)一個(gè)數(shù)組中的元素進(jìn)行處理,全部處理完成后再執(zhí)行一個(gè)last操作。但是JS的異步特性會(huì)使這個(gè)last語(yǔ)句先執(zhí)行,所以花點(diǎn)時(shí)間研究研究forEach。

Talk is cheap. Show me the code.

forEach 用法

forEach用于對(duì)數(shù)組結(jié)構(gòu)進(jìn)行遍歷,看到有人說(shuō)forEach底層是用for實(shí)現(xiàn)的,沒(méi)深究,起碼效果上看是一樣的。forEach的回調(diào)函數(shù)3個(gè)參數(shù)分別是:值、序號(hào)和原數(shù)組。序號(hào)從0開(kāi)始。

?
1
2
3
4
5
6
7
8
9
(() => {
  let arr = [2, 3, 1];
  arr.forEach(function (value, index, array) {
    console.log(value);
    console.log(index);
    console.log(array);
    console.log('-----');
  });
})();

Output

?
1
2
3
4
5
6
7
8
9
10
11
12
2
0
[ 2, 3, 1 ]
-----
3
1
[ 2, 3, 1 ]
-----
1
2
[ 2, 3, 1 ]
-----

從結(jié)果上看forEach多次循環(huán)之間是同步的,也就是說(shuō)都是按順序執(zhí)行的。但是一想到它是JS就感覺(jué)不可能同步的。。可以驗(yàn)證一下。

forEach 異步處理多次循環(huán)

這次在forEach加個(gè)定時(shí)任務(wù),每次循環(huán)操作都延時(shí)value相關(guān)的時(shí)間,模擬比較耗時(shí)的操作。

?
1
2
3
4
5
6
7
8
(() => {
  let arr = [2, 3, 1];
  arr.forEach(function (value, index, array) {
    setTimeout(function () {
      console.log(value);
    }, value*100);
  });
})();

Output

?
1
2
3
1
2
3

從結(jié)果可以看出耗時(shí)最短的任務(wù)先完成,每次循環(huán)的任務(wù)并不是按循環(huán)的先后順序執(zhí)行的,也就是說(shuō)異步處理多次循環(huán)。

forEach 上下文也是異步執(zhí)行

回到開(kāi)始說(shuō)到的問(wèn)題了,且不管多次循環(huán)是不是按順序執(zhí)行,我需要forEach中的所有任務(wù)都完成后執(zhí)行一條數(shù)據(jù)來(lái)通知我任務(wù)全部完成了。

?
1
2
3
4
5
6
7
8
9
(() => {
  let arr = [2, 3, 1];
  arr.forEach(function (value, index, array) {
    setTimeout(function () {
      console.log(value);
    }, value*100);
  });
  console.log('All the work is done');
})();

Output

?
1
2
3
4
All the work is done
1
2
3

從結(jié)果來(lái)看,上下文的語(yǔ)句也不是同步的,forEach循環(huán)中的任務(wù)沒(méi)有完成就通知所有任務(wù)都完成了,顯然不符合預(yù)期。

針對(duì)這個(gè)問(wèn)題看了好多個(gè)博客,都沒(méi)有找到合適的解決方法,最后只能想到用Promise.all來(lái)勉強(qiáng)實(shí)現(xiàn)這個(gè)功能。

Promise.all 實(shí)現(xiàn) forEach 上下文語(yǔ)句同步處理

把上面的代碼改成Promise.all的結(jié)構(gòu)。每個(gè)循環(huán)中執(zhí)行結(jié)束調(diào)用resolve(),我們知道Promise.all的then函數(shù),只有所有的Promise都執(zhí)行完成才會(huì)觸發(fā),這樣好像能滿足我們的需求。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(() => {
  let arr = [2, 3, 1];
  let proArr = [];
  arr.forEach(function (value, index) {
    proArr[index] = new Promise(function (resolve) {
      setTimeout(function () {
        console.log(value);
        resolve();
      }, value*100);
    });
  });
  Promise.all(proArr).then(()=>{
    console.log('All the work is done');
  })
})();

Output

?
1
2
3
4
1
2
3
All the work is done

從結(jié)果來(lái)看,滿足了我們的需求。

可能還存在的問(wèn)題

想到JS異步特性,突然發(fā)現(xiàn)可能這個(gè)方法還存在個(gè)問(wèn)題。

這里每次 forEach 剛進(jìn)入就對(duì) Promise 數(shù)組進(jìn)行了賦值操作,這個(gè)操作時(shí)間應(yīng)該非常短,循環(huán)3次都賦值完成后才調(diào)用最后的Promise.all語(yǔ)句。

但是如果這個(gè)數(shù)組非常大,這個(gè)循環(huán)賦值的操作非常耗時(shí)間的話,假如只完成了一半的賦值操作,那么執(zhí)行最后這個(gè) Promise.all 的時(shí)候傳入的 Promise 數(shù)組可能并不是包含所有 Promise 的數(shù)組。

這樣的話 Promise.all 等待的就只有一半的操作,Promise.all 等待的時(shí)候,這個(gè)數(shù)組后面被賦值的 Promise 不知道會(huì)不會(huì)被等待。

剛接觸JS不明白實(shí)現(xiàn)機(jī)制,只能實(shí)驗(yàn)來(lái)驗(yàn)證一下是否存在這個(gè)問(wèn)題。接下來(lái)用把這個(gè)數(shù)組弄大一些,請(qǐng)?jiān)徫矣米钌倒鲜降姆绞礁愦笏?/p>

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
(() => {
  let arr = [2, 3, 1, 2, 3, 1, 2, 3, 1, 2];  // 10
  arr= arr.concat(arr);  // 2^1 * 10
  arr= arr.concat(arr);  // 2^2 * 10
  arr= arr.concat(arr);  // 2^3
  arr= arr.concat(arr);  // 2^4
  arr= arr.concat(arr);  // 2^5
  arr= arr.concat(arr);
  arr= arr.concat(arr);
  arr= arr.concat(arr);
  arr= arr.concat(arr);
  arr= arr.concat(arr);  // 2^10
  arr= arr.concat(arr);
  arr= arr.concat(arr);
  arr= arr.concat(arr);
  arr= arr.concat(arr);
  arr= arr.concat(arr);  // 2^15
  arr= arr.concat(arr);
  arr= arr.concat(arr); // 2^17 * 10
// arr= arr.concat(arr);  // 2^18 * 10
  console.log(arr.length);
  let proArr = [];
  arr.forEach(function (value, index) {
    proArr[index] = new Promise(function (resolve) {
      setTimeout(function () {
        console.log(value);
        resolve();
      }, value*100);
    });
  });
  Promise.all(proArr).then(()=>{
    console.log('All the work is done');
    console.log(arr.length);
  }).catch(function (err) {
    console.log(err);
  })
})();

經(jīng)過(guò)測(cè)試在我這個(gè)電腦上當(dāng)數(shù)組長(zhǎng)度為2^18 * 10的時(shí)候,Promise報(bào)錯(cuò) RangeError: Too many elements passed to Promise.all。

當(dāng)數(shù)組長(zhǎng)度為2^17 * 10 即2621440的時(shí)候,會(huì)正常運(yùn)行。測(cè)試了幾次,最后的執(zhí)行命令輸出的All the work is done始終在最后輸出(因?yàn)榻K端緩沖區(qū)太小,所以使用node xx.js > log.txt重定向的方式把輸出結(jié)果重定向到文件查看)。

當(dāng)然應(yīng)用中也不會(huì)有這么大的數(shù)組,從結(jié)果看的話,就是實(shí)際應(yīng)用中不存在上面考慮可能出現(xiàn)的問(wèn)題。

也就是說(shuō)可以用 Promise.all 實(shí)現(xiàn) forEach 上下文語(yǔ)句同步處理。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

原文鏈接:https://blog.csdn.net/WificamSDK7/article/details/78460408

延伸 · 閱讀

精彩推薦
  • node.jsrequire加載器實(shí)現(xiàn)原理的深入理解

    require加載器實(shí)現(xiàn)原理的深入理解

    這篇文章主要給大家介紹了關(guān)于require加載器實(shí)現(xiàn)原理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需...

    隱冬8462022-03-03
  • node.jsnodejs中使用worker_threads來(lái)創(chuàng)建新的線程的方法

    nodejs中使用worker_threads來(lái)創(chuàng)建新的線程的方法

    這篇文章主要介紹了nodejs中使用worker_threads來(lái)創(chuàng)建新的線程的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友...

    flydean程序那些事8982022-01-06
  • node.js在瀏覽器中,把 Vite 跑起來(lái)了!

    在瀏覽器中,把 Vite 跑起來(lái)了!

    大家好,我是 ssh,前幾天在推上沖浪的時(shí)候,看到 Francois Valdy 宣布他制作了 browser-vite[1],成功把 Vite 成功在瀏覽器中運(yùn)行起來(lái)了。這引起了我的興趣,如...

    前端從進(jìn)階到入院9282022-01-11
  • node.js詳解node.js創(chuàng)建一個(gè)web服務(wù)器(Server)的詳細(xì)步驟

    詳解node.js創(chuàng)建一個(gè)web服務(wù)器(Server)的詳細(xì)步驟

    這篇文章主要介紹了詳解node.js創(chuàng)建一個(gè)web服務(wù)器(Server)的詳細(xì)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,...

    王佳斌8952021-12-31
  • node.jslinux服務(wù)器快速卸載安裝node環(huán)境(簡(jiǎn)單上手)

    linux服務(wù)器快速卸載安裝node環(huán)境(簡(jiǎn)單上手)

    這篇文章主要介紹了linux服務(wù)器快速卸載安裝node環(huán)境(簡(jiǎn)單上手),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需...

    mose-x8462022-01-22
  • node.jsNode.js ObjectWrap 的弱引用問(wèn)題

    Node.js ObjectWrap 的弱引用問(wèn)題

    最近在寫(xiě) Node.js Addon 的過(guò)程中,遇到了一個(gè)問(wèn)題,然后發(fā)現(xiàn)是 ObjectWrap 弱引用導(dǎo)致的,本文介紹一下具體的問(wèn)題和排查過(guò)程,以及 ObjectWrap 的使用問(wèn)題。...

    編程雜技9852022-01-04
  • node.jsNode.js 中如何收集和解析命令行參數(shù)

    Node.js 中如何收集和解析命令行參數(shù)

    這篇文章主要介紹了Node.js 中如何收集和解析命令行參數(shù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋...

    descire8802021-12-28
  • node.jsk8s node節(jié)點(diǎn)重新加入master集群的實(shí)現(xiàn)

    k8s node節(jié)點(diǎn)重新加入master集群的實(shí)現(xiàn)

    這篇文章主要介紹了k8s node節(jié)點(diǎn)重新加入master集群的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋...

    Scarborought13922022-01-22
1239
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 国产精品久久久久久久不卡 | av电影在线观看网址 | 日本在线免费观看视频 | 亚洲第一色婷婷 | 黄色毛片免费看 | 曰韩av在线 | 19禁国产精品福利视频 | 亚洲一区在线免费视频 | 成人国产免费观看 | 一区二区三区四区在线观看视频 | 久久伊人精品热在75 | 亚洲天堂在线电影 | 91九色视频观看 | 欧美性生活久久久 | 国产精品久久77777 | 爱操成人网 | 亚洲视频成人在线 | 亚洲一级片在线观看 | 免费福利在线视频 | 中午字幕无线码一区2020 | 成人免费一区二区三区 | 国产免费观看a大片的网站 欧美成人一级 | 国产免费最爽的乱淫视频a 午夜精品久久久久久久99热浪潮 | 亚洲四播房 | 国产乱淫a∨片免费观看 | 久久99精品久久 | 久久国产精品久久久久久电车 | 99久久久国产精品免费99 | 国产91丝袜在线播放 | 国产一精品久久99无吗一高潮 | 欧美一级h| 免费永久看羞羞片网站入口 | 国产人成免费爽爽爽视频 | 欧美成年私人网站 | 国产亚洲精品综合一区 | 日本在线视频二区 | 婷婷亚洲一区二区三区 | 关键词 | 午夜精品视频在线 | 斗破苍穹在线观看免费完整观看 | 欧美成人一级 |