第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

node js怎么判斷循環(huán)結(jié)束了?

node js怎么判斷循環(huán)結(jié)束了?

函數(shù)式編程 2018-10-24 22:18:38
node js怎么判斷循環(huán)結(jié)束了
查看完整描述

1 回答

?
呼啦一陣風(fēng)

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超6個(gè)贊

Node.js 的異步機(jī)制由事件和回調(diào)函數(shù)實(shí)現(xiàn),一開始接觸可能會(huì)感覺違反常規(guī),但習(xí)慣  以后就會(huì)發(fā)現(xiàn)還是很簡(jiǎn)單的。然而這之中其實(shí)暗藏了不少陷阱,一個(gè)很容易遇到的問題就是  循環(huán)中的回調(diào)函數(shù),初學(xué)者經(jīng)常容易陷入這個(gè)圈套。讓我們從一個(gè)例子開始說明這個(gè)問題。

  • var fs = require('fs');

  • var files = ['a.txt', 'b.txt', 'c.txt'];


  • for (var i = 0; i < files.length; i++) {

  • fs.readFile(files[i], 'utf-8', function (err, contents) {

  • console.log(files[i] + ': ' + contents);


  • });

  • }

  • 這段代碼的功能很直觀,就是依次讀取文件 a.txt、b.txt 、c.txt ,并輸出文件名和內(nèi)容。假設(shè)這三個(gè)文件的內(nèi)容分別是 AAA 、BBB 和 CCC,那么我們期望的輸出結(jié)果就是:

    a.txt: AAA

    b.txt: BBB

    c.txt: CCC

    可是我們運(yùn)行這段代碼的結(jié)果是怎樣的呢?竟然是這樣的結(jié)果:

    undefined: AAA

    undefined: BBB

    undefined: CCC

    這個(gè)結(jié)果說明文件內(nèi)容正確輸出了,而文件名卻不對(duì),也就意味著,contents 的結(jié)果是正確的,但 files[i] 的值是 undefined。這怎么可能呢,文件名不正確卻能讀取文件內(nèi)容?既然難以直觀地理解,我們就把 files[i] 分解并打印出來看看,在讀取文件的回調(diào)函數(shù)中分別輸出 files、i 和 files[i] 。

  • var fs = require('fs');

  • var files = ['a.txt', 'b.txt', 'c.txt'];

  • for (var i = 0; i < files.length; i++) {

  • fs.readFile(files[i], 'utf-8', function (err, contents) {

  • console.log(files);

  • console.log(i);

  • console.log(files[i]);

  • });

  • }


  • 運(yùn)行修改后的代碼,結(jié)果如下:

    [ 'a.txt', 'b.txt', 'c.txt' ]

    3

    undefined

    [ 'a.txt', 'b.txt', 'c.txt' ]

    3

    undefined

    [ 'a.txt', 'b.txt', 'c.txt' ]

    3

    undefined

    看到這里是不是有點(diǎn)啟發(fā)了呢?三次輸出的 i 的值都是 3 ,超出了 files 數(shù)組的下標(biāo)范圍,因此 files[i] 的值就是 undefined 了。這種情況通常會(huì)在 for 循環(huán)結(jié)束時(shí)發(fā)生,例如 for (var i = 0; i < files.length; i++),退出循環(huán)時(shí) i 的值就files.length 的值。既然 i 的值是 3 ,那么說明了事實(shí)上 fs.readFile 的回調(diào)函數(shù)中訪問到的 i 值都是循環(huán)退出以后的,因此不能分辨。而 files[i] 作為 fs.readFile 的第一個(gè)參數(shù)在循環(huán)中就傳遞了,所以文件可以被定位到,而且可以顯示出文件的內(nèi)容。

    現(xiàn)在問題就明朗了:原因是3 次讀取文件的回調(diào)函數(shù)事實(shí)上是同一個(gè)實(shí)例,其中引用到的 i 值是上面循環(huán)執(zhí)行結(jié)束后的值,因此不能分辨。如何解決這個(gè)問題呢?我們可以利用

    JavaScript 函數(shù)式編程的特性,手動(dòng)建立一個(gè)閉包:

    //forloopclosure.js

  • var fs = require('fs');


  • var files = ['a.txt', 'b.txt', 'c.txt'];


  • for (var i = 0; i < files.length; i++) {

  • (function (i) {

  • fs.readFile(files[i], 'utf-8', function (err, contents) {

  • console.log(files[i] + ': ' + contents);

  • });

  • })(i);

  • }

  • 上面代碼在 for 循環(huán)體中建立了一個(gè)匿名函數(shù),將循環(huán)迭代變量 i 作為函數(shù)的參數(shù)傳遞并調(diào)用。由于運(yùn)行時(shí)閉包的存在,該匿名函數(shù)中定義的變量(包括參數(shù)表)在它內(nèi)部的函數(shù)(fs.readFile 的回調(diào)函數(shù))執(zhí)行完畢之前都不會(huì)釋放,因此我們?cè)谄渲性L問到的 i 就分別是不同的閉包實(shí)例,這個(gè)實(shí)例是在循環(huán)體執(zhí)行的過程中創(chuàng)建的,保留了不同的值。

    補(bǔ)充:閉包的寫法,無(wú)法保證按數(shù)組存放文件順序讀取文件內(nèi)容,相當(dāng)多個(gè)文件讀取操作并行進(jìn)行,根據(jù)文件大小決定讀取的快慢;而forEach是可以的保證順序讀取;

    事實(shí)上以上這種寫法并不常見,因?yàn)樗档土顺绦虻目勺x性,故不推薦使用。大多數(shù)情況下我們可以用數(shù)組的 forEach 方法解決這個(gè)問題:

    //callbackforeach.js

  • var fs = require('fs');

  • var files = ['a.txt', 'b.txt', 'c.txt'];

  • files.forEach(function (filename) {

  • fs.readFile(filename, 'utf-8', function (err, contents) {

  • console.log(filename + ': ' + contents);

  • });

  • });




查看完整回答
反對(duì) 回復(fù) 2018-11-18
  • 1 回答
  • 0 關(guān)注
  • 1544 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)