成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【筆記】你不知道的JS讀書筆記——Promise

mumumu / 792人閱讀

摘要:寫在前面這一章的順序?qū)τ谖唇佑|過使用過的童鞋而言略抽象了,前邊幾章主要為了說明和之前的異步方式相比有什么優(yōu)勢(shì)和它能解決什么問題,后邊才詳解的設(shè)計(jì)和各種場(chǎng)景下如何使用。建議先了解和簡(jiǎn)單使用過后再閱讀,效果更佳。

寫在前面:
Promise這一章的順序?qū)τ谖唇佑|過使用過Promise的童鞋而言略抽象了,前邊幾章主要為了說明Promise和之前的異步方式相比有什么優(yōu)勢(shì)和它能解決什么問題,后邊才詳解Promise的API設(shè)計(jì)和各種場(chǎng)景下如何使用Promise。

建議先了解和簡(jiǎn)單使用過Promise后再閱讀,效果更佳。

正文

3.1 什么是Promise

之前的方式:

利用回調(diào)函數(shù)封裝程序中的continuation

回調(diào)交給第三方

第三方調(diào)用回調(diào)

實(shí)現(xiàn)正確功能

Promise方式:
第三方提供了解其任務(wù)何時(shí)結(jié)束的能力

Promise的異步特性是基于任務(wù)的(圖示如下)

一種處理異步的思路:為了統(tǒng)一現(xiàn)在和將來,把它們都變成將來,即所有操作都成了異步的

書中關(guān)于Promise是個(gè)啥的觀點(diǎn):

一種封裝和組合未來值的易于復(fù)用的機(jī)制
一種在異步任務(wù)中作為兩個(gè)或更多步驟的流程控制機(jī)制,時(shí)序上的this-then-that —— 關(guān)注點(diǎn)分離

Promise設(shè)計(jì)的重要基礎(chǔ)

Promise一定是異步執(zhí)行的,即使是立即完成的Promise(類似 new Promise((resolve)=>{ resolve(42) })),也無法被同步觀察到

一旦Promise決議,它就永遠(yuǎn)保持在這個(gè)狀態(tài),變成了不變值(immuatable value),這是設(shè)計(jì)中最基礎(chǔ)和最重要的因素

Promise至多只能有一個(gè)決議值(一個(gè)!一個(gè)!一個(gè)?。?/p>

引申:

Promise的決議結(jié)果可以給多方多次查看

安全、可靠

3.2 Promise的檢測(cè)

基于thenable的鴨子類型

if(
  p !== null && 
  (
    typeof p === "object" ||
    typeof p === "function"
  ) && 
  typeof p.then === "function"
) {
  // 假定這是一個(gè)thenable
}
else {
  // 不是thenable
}

這種方式顯然是有些問題的,但是目前通用的方式

3.3 Promise如何解決信任問題

信任問題見 異步篇

3.3.1 調(diào)用過早

避免Zalgo這類副作用:一個(gè)任務(wù)有時(shí)同步完成,有時(shí)異步完成,可能導(dǎo)致競(jìng)態(tài)條件

Promise從定義上保證了不會(huì)存在這種問題:參考3.1 設(shè)計(jì)基礎(chǔ) — 即使是立即完成的Promise,也無法被同步觀察到

3.3.2 調(diào)用過晚

Note: 調(diào)用過晚強(qiáng)調(diào)的是調(diào)用順序?

Promise創(chuàng)建對(duì)象調(diào)用resolve(..)或reject(..)時(shí),這個(gè)Promise的then注冊(cè)的觀察回調(diào)就會(huì)自動(dòng)調(diào)度(注意是被調(diào)度而不是執(zhí)行) —— 在下一個(gè)異步時(shí)機(jī)點(diǎn)上依次被調(diào)用執(zhí)行,它們相互之間是不會(huì)互相影響或延誤的

3.3.3 回調(diào)未調(diào)用

Promise一旦決議則一定會(huì)通知決議(傳入then的完成回調(diào)或拒絕回調(diào)調(diào)用),即使是Javascript運(yùn)行錯(cuò)誤也會(huì)調(diào)用拒絕回調(diào)

如果某個(gè)Promise一直不決議呢?使用競(jìng)態(tài)的高級(jí)抽象機(jī)制:

// 超時(shí)工具
function timeoutPromise(delay){
  return new Promise( (resolve, reject) => {
    setTimeout( function () {
      reject("Timeout!");
    }, delay);
  } )
}

// 設(shè)置某個(gè)Promise foo()超時(shí)
Promise.race( [
  foo(),
  timeoutPromise(3000)
] )
.then(
  function () {
    // foo(..)及時(shí)完成
  },
  function (err) {
    // foo(..)被拒絕或者超時(shí)
    // 通過查看err確定錯(cuò)誤情況
  }
);
3.3.4 調(diào)用次數(shù)過少或過多

如果創(chuàng)建Promise的代碼試圖多次調(diào)用resolve(..)或reject(..),或者兩者都調(diào)用,Promise只會(huì)接受第一次決議,后續(xù)調(diào)用都會(huì)被忽略

3.3.5 未能傳遞參數(shù)/環(huán)境值

Promise至多只能有一個(gè)決議值

如果使用多個(gè)參數(shù)調(diào)用resolve(..)或reject(..),第一個(gè)參數(shù)之后的所有參數(shù)都會(huì)被忽略

Promise其實(shí)也是傳入回調(diào)函數(shù),故函數(shù)中照樣能根據(jù)作用域規(guī)則訪問到對(duì)應(yīng)的環(huán)境數(shù)據(jù)

3.3.6 吞掉錯(cuò)誤或異常

這里說的錯(cuò)誤或異常可能出現(xiàn)在兩個(gè)過程:

Promise創(chuàng)建過程或其決議確認(rèn)之前的任何時(shí)間點(diǎn)上(注:書中原文查看其決議結(jié)果過程中任何時(shí)間點(diǎn),個(gè)人認(rèn)為可能翻譯得有點(diǎn)問題,應(yīng)該要強(qiáng)調(diào)是其決議之前)

Promise決議確認(rèn)后在查看結(jié)果時(shí)(then(..)注冊(cè)的回調(diào)中)出現(xiàn)了js異常錯(cuò)誤

這兩種錯(cuò)誤都不會(huì)被丟棄,但針對(duì)它們的處理方式有所不同:

針對(duì)1:
該P(yáng)romise會(huì)被立即拒絕,但注意這個(gè)異常也被變成了異步行為

let p = new Promise ( function(resolve, reject){
    foo.bar(); // foo undefined 將拋出錯(cuò)誤 Promise=>reject
    resolve( 42 ); // 不會(huì)執(zhí)行到這里
});
p.then(
    function fulfilled(){
        // 不會(huì)執(zhí)行到這里
    },
    function rejected(err){
        // err是一個(gè)TypeError異常
    }
)

針對(duì)2:
這個(gè)時(shí)候當(dāng)前Promise已經(jīng)決議,其決議結(jié)果是個(gè)不可變值
then(..)調(diào)用返回的下一個(gè)Promise被拒絕

let q = new Promise ( function(resolve, reject){
    resolve( 42 );
})
q.then(
    function fulfilled(){
        foo.bar(); // foo undefined 將拋出錯(cuò)誤 導(dǎo)致then返回的Promise被reject
    },
    function rejected(err){
        // 不會(huì)執(zhí)行到這里
    }
).then(
    function fulfilled(){
        // 不會(huì)執(zhí)行到這里
    },
    function rejected(err){
        // err是一個(gè)TypeError異常
    }
)          
3.3.7 構(gòu)建可信任的Promise

Promise.resolve(..) 規(guī)范化傳入的值:

傳入一個(gè)非Promise、非thenable的立即值, 會(huì)得到一個(gè)用該值填充的Promise

傳入一個(gè)真正的Promise,會(huì)返回同一個(gè)Promise

傳入一個(gè)非Promise的thenable值,會(huì)試圖展開這個(gè)值,持續(xù)到提取出一個(gè)具體的非類Promise的最終值

具體看例子(傳入Promise的情況略)

// 傳入一個(gè)立即值
let p = Promise.resolve(42);
p.then( res => {
    console.log("Promise.resolve(42).then:",res);
})
let p1 = Promise.resolve({});
p1.then( res => {
    console.log("Promise.resolve({}).then:",res);
})
// 傳入一個(gè) thenable 嘗試展開
let p2 = Promise.resolve({
    then: function(cb) { cb(42)}
});
p2.then( res => {
    console.log("Promise.resolve(thenable).then:", res);
}, err => {
    console.log("Promise.resolve(thenable).then:", err);
})
// 注意 這種情況其實(shí)也是立即值?。?!
let p3 = Promise.resolve(
    setTimeout(()=>{
        return "inside a continuation"  
    },1000)
); // settimeout函數(shù)返回當(dāng)前定時(shí)器引用=>耶 立即值
p3.then( res => {
    console.log("Promise.resolve(看起來是個(gè)異步).then:", res); 
})
3.4 Promise鏈?zhǔn)搅?/b>

Promise不僅僅是一個(gè)單步執(zhí)行this-then-that的操作機(jī)制,這只是它的構(gòu)成部件,實(shí)際上Promise是可以連接到一起使用表示一系列異步步驟:

每次對(duì)Promise調(diào)用then(..),它都會(huì)創(chuàng)建并返回一個(gè)新的Promise,我們可以將其鏈接起來;(并不局限于要求then中返回一個(gè)Promise)

不管從then(..)調(diào)用的完成回調(diào)(第一個(gè)參數(shù))返回的值是什么,它都會(huì)被自動(dòng)設(shè)置為被鏈接Promise(上一點(diǎn)中的)的完成(resolve)(一定要理解這句話)

再仔細(xì)看看第二點(diǎn),結(jié)合上文 3.3.7 Promise.resolve(..)的能力,這是Promise鏈?zhǔn)搅髟诿恳徊蕉寄苡挟惒侥芰Φ年P(guān)鍵!

栗子:

// 返回立即值

    let p = Promise.resolve(21);
    p
    .then( function(v) {
        console.log(v);  // 21

        // 返回立即值
        return v * 2;
    })
    // 這里是鏈接的Promise
    .then ( function(v) {
        console.log(v);  // 42
    });
// 返回Promise并引入異步

    let p = Promise.resolve(21);
    p
    .then ( function(v) {
        // 返回一個(gè)異步Promise
        return new Promise( (resolve, reject) => {
            setTimeout(() => {
                resolve(v*2);
            }, 1000);
        });
    })
    .then ( function(v) {
        // 前一步延遲1s后執(zhí)行
        console.log(v);
    })

Promise鏈不僅僅是一個(gè)表達(dá)多步異步序列的流程控制,還可以從一個(gè)步驟到下一個(gè)步驟的消息通道

3.5 錯(cuò)誤處理

幾種錯(cuò)誤處理方式:

try...catch結(jié)構(gòu)不能應(yīng)用于異步模式

    function foo() {
        setTimeout(() => {
            baz.bar();  // 錯(cuò)誤代碼
        }, 100);
    }
    try{
        foo();  // 之后將拋出全局錯(cuò)誤
    }
    catch (err) {
        // 不會(huì)走到這里
    }

foo()中有自己的異步完成函數(shù),其中任何異步錯(cuò)誤都無法捕捉到

node.js api或庫中常見的err-first模式

    function foo(cb) {
        setTimeout(() => {
            try {
                var x = baz.bar();  //  錯(cuò)誤代碼
                cb(null, x);
            }
            catch (err) {
                cb(err);
            }
        }, 100);
    }

    foo( function(err, val) {
        if(err) {
            console.error(err);  //  報(bào)錯(cuò)惹
        }
        else {
            console.log(val);
        }
    })

分離回調(diào)模式(split-callback)
一個(gè)回調(diào)用于完成情況,一個(gè)回調(diào)用于拒絕情況
Promise采用的就是這種方式

先參考 3.3.6 再進(jìn)行詳細(xì)討論:

Promise決議前、決議后產(chǎn)生的錯(cuò)誤處理方式有所不同
錯(cuò)誤的使用Promise API產(chǎn)生的錯(cuò)誤會(huì)阻礙正常Promise對(duì)象的構(gòu)造,這種情況下會(huì)立即拋出異常(這種情況應(yīng)該死都不要出現(xiàn) 0 0)

3.5.1 絕望的陷阱

由于Promise鏈?zhǔn)教攸c(diǎn),其鏈上的最后一步,不管是什么,總是存在著在未被查看的Promise中出現(xiàn)未捕獲錯(cuò)誤的可能性

即理論上來說:總有可能有錯(cuò)誤未被捕獲,而出現(xiàn)全局報(bào)錯(cuò)

P.S. 這也是個(gè)人認(rèn)為使用Promise最頭疼的一點(diǎn)

3.5.2 處理未捕獲的情況

關(guān)于如何解決3.5.1提出問題的一些思路

增加done(..)作為鏈?zhǔn)秸{(diào)用的終點(diǎn),在其中可以查看未捕獲的錯(cuò)誤,并且不會(huì)創(chuàng)建和返回新的Promise

依靠瀏覽器 追蹤Promise對(duì)象在被垃圾回收時(shí)是否有拒絕(未捕獲的錯(cuò)誤),獲得其報(bào)告 (什么功能?@TODO),可是如果Promise未被垃圾回收呢?

3.5.2 成功的坑

該小節(jié)討論的是從作者角度提出一種避免在使用Promise時(shí)在開發(fā)者未注意的情況下出現(xiàn)未捕獲錯(cuò)誤而報(bào)出全局錯(cuò)誤的方案

具體請(qǐng)看:

{
    let p = Promise.reject(21); // 將觸發(fā)全局報(bào)錯(cuò) Uncaught (in promise) 21

    let p1 = Promise.reject(21).then (  // 拒絕前,注冊(cè)了一個(gè)錯(cuò)誤處理函數(shù)
        (res) => {
            // 不會(huì)走到這里 
        },
        (err) => {
            console.log(`注冊(cè)了一個(gè)錯(cuò)誤處理函數(shù):${err}`);
        }
    )
    Promise.prototype.defer = function (){
        // 作者提出的一個(gè)API  
        // 簡(jiǎn)單實(shí)現(xiàn)就是單純的返回這個(gè)Promise本身 
        return this;
    }

    let p2 = Promise.reject(21).defer(); // p2的結(jié)果在將來會(huì)被查看,現(xiàn)在暫時(shí)不要報(bào)全局錯(cuò)誤

    let foo = Promise.resolve(21);

    foo
    .then (function(v) {
        return p2; // 這里查看p2的結(jié)果
    }, function (err) {
        // 不會(huì)走到這里
    })
    .catch (function(v) {
        console.log(v); // p2的結(jié)果
    })
}
3.6 Promise模式

基于Promise構(gòu)建的異步抽象模式

3.6.1 Promise.all([ .. ])

類似門(gate)這種機(jī)制:需要等待兩個(gè)或更多并行/并發(fā)的任務(wù)都完成才能繼續(xù),它們的完成順序并不重要,但必須都要完成,門才能打開并讓流程控制繼續(xù)

Promise.all([ .. ])的參數(shù)接收一個(gè)數(shù)組:

數(shù)組中的每個(gè)值都會(huì)交給Promise.resolve(..) 過濾以保證傳入值是一個(gè)真正的Promise (Promise.resolve(..)的作用參考 3.3.7 構(gòu)建可信任的Promise

數(shù)組為空,主promise就會(huì)立即完成

返回一個(gè)Promise:

傳入的所有promise完成,該promise標(biāo)記完成,返回消息是一個(gè)由所有傳入promise的完成消息組成的數(shù)組,與調(diào)用API時(shí)傳入的順序一致(與完成順序無關(guān))

如果傳入的promise中有任何一個(gè)被拒絕的話,該promise會(huì)立即被拒絕,并丟棄來自其他所有promise的全部結(jié)果(其他promise還是會(huì)執(zhí)行),返回錯(cuò)誤消息是被拒絕的那個(gè)promise的錯(cuò)誤消息(注意,promise一旦決議結(jié)果不會(huì)變更,故僅有第一個(gè)被拒絕的promise錯(cuò)誤消息會(huì)被主promise返回)

每個(gè)promise都必須關(guān)聯(lián)一個(gè)拒絕/錯(cuò)誤處理函數(shù),特別是從Promise.all([ ... ])返回的那一個(gè)

3.6.2 Promise.race([ ... ])

類似門閂(shuan)競(jìng)態(tài):一旦有任何一個(gè)Promise決議為完成,就標(biāo)記為完成;一旦有任何一個(gè)Promise決議為拒絕,它就會(huì)拒絕

Promise.race([ ... ])的參數(shù)接收一個(gè)數(shù)組:

被Promise.resolve(...)過濾那是當(dāng)然的

傳入立即值沒有任何意義,肯定是第一個(gè)立即值取勝

如果傳入一個(gè)空數(shù)組,會(huì)導(dǎo)致該P(yáng)romise永遠(yuǎn)不會(huì)決議!千萬不要這么做

返回一個(gè)Promise:

和Promise.all([ ... ])不同,返回消息不是一個(gè)數(shù)組,因?yàn)橹荒芙邮找粋€(gè)promise的完成消息

關(guān)于這兩個(gè)API需要注意

在all和race中存在著被忽略或丟棄的promise,如果這些promise中保存著重要的數(shù)據(jù)或資源或者開發(fā)者需要記錄這些promise失敗的事實(shí),又該怎么辦呢?

finally API就是基于這種情況提出的:Promise需要一個(gè)finally(...)回調(diào)注冊(cè),這個(gè)回調(diào)在Promise決議后總是會(huì)被調(diào)用,并允許執(zhí)行任何必要的清理工作

注:書中提到finally還未被規(guī)范支持,而在18年1月已經(jīng)正式加入到提案中了,可參考 https://github.com/tc39/propo... 和 https://github.com/tc39/propo...

書中還提到了一種觀察模式(基于同一個(gè)Promise決議可以被多次查看),具體可以看栗子

    let foo = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(21);
        }, 301);
    });
    let timeout = function(time) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve("timeout");
            }, time);
        })
    }
    // foo會(huì)被默默忽略
    Promise.race( [
        foo, 
        timeout(300)
    ])
    .then( (res) => {
        console.log(`Promise.race: ${res}`);
    })
    .finally( (res) => {
        console.log(`Promise.race: ${res}`);    // finally回調(diào)是不會(huì)提供任何參數(shù)的,詳情可看 https://github.com/tc39/proposal-promise-finally
    })
    // 觀察者模式
    if(!Promise.observe){
        Promise.observe = function(pr, cb){
            // 觀察pr的決議
            pr.then( 
                function fulfilled (msg){
                    // 完成時(shí)
                    Promise.resolve(msg).then(cb);
                },
                function reject (msg){
                    // 拒絕時(shí) 傳遞錯(cuò)誤消息 但注意觀察者promise是resolve的
                    Promise.resolve(msg).then(cb);
                }
            );
            // 返回最初的promise
            return pr;
        }
    }
    // 還是上一個(gè)超時(shí)的例子
    Promise.race( [
        Promise.observe(
            foo,
            function cleanup (msg){
                console.log(`Promise.observe: ${msg}`); // foo即使沒有在超時(shí)之前完成 也可以獲取其決議情況
            }
        )
        .then 
    ])
3.6.3 all([ .. ])和race([ .. ])的變體


@TODO 自行實(shí)現(xiàn) Promise.any finally map等擴(kuò)展API

3.6.4 并發(fā)迭代

實(shí)現(xiàn)一個(gè)異步的map(..)工具

接收一個(gè)數(shù)組的值(可以是Promise或其他值)

接收一個(gè)在每個(gè)值上運(yùn)行的一個(gè)函數(shù)

返回一個(gè)Promise,其完成值是一個(gè)數(shù)組,該數(shù)組保存任務(wù)執(zhí)行之后的異步完成值(保持映射順序)

這里也主要看栗子

   if(!Promise.map) {
        Promise.map = function(vals, cb) {
            // 等待所有map的promise決議的新的promise
            return Promise.all(
                // 對(duì)vals使用map將每個(gè)值轉(zhuǎn)出promise,值數(shù)組->Promise數(shù)組
                vals.map( function(val){
                    // 將val值替換成調(diào)用cb函數(shù)后決議的新的promise
                    return new Promise( function(resolve){
                        // resolve reject傳入到cb函數(shù)中
                        cb(val, resolve);
                    })
                })
            )
        }
    }
    // 使用Promise.map
    var p1 = Promise.resolve(21);
    var p2 = Promise.resolve(30);
    var p3 = Promise.reject("opps");

    Promise.map( [p1,p2,p3], function(pr, resolve){
        Promise.resolve(pr)
        .then( val => {
            resolve( val*2 );
        },
            resolve  // 注意:不能發(fā)出拒絕信號(hào),如果發(fā)出會(huì)導(dǎo)致Promise.map被拒絕,其他map結(jié)果也會(huì)被丟棄
        )
    })
    .then( (vals) => {
        console.log(vals);
    })

TODO:
Promise API 概述詳解多帶帶成篇

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94606.html

相關(guān)文章

  • 筆記你不知道JS讀書筆記——異步

    摘要:異步請(qǐng)求線程在在連接后是通過瀏覽器新開一個(gè)線程請(qǐng)求將檢測(cè)到狀態(tài)變更時(shí),如果設(shè)置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,將這個(gè)回調(diào)再放入事件循環(huán)隊(duì)列中。 基礎(chǔ):瀏覽器 -- 多進(jìn)程,每個(gè)tab頁獨(dú)立一個(gè)瀏覽器渲染進(jìn)程(瀏覽器內(nèi)核) 每個(gè)瀏覽器渲染進(jìn)程是多線程的,主要包括:GUI渲染線程 JS引擎線程 也稱為JS內(nèi)核,負(fù)責(zé)處理Javascript腳本程序。(例如V8引擎) JS引擎線程負(fù)...

    junnplus 評(píng)論0 收藏0
  • 你不知道JavaScript》 (中) 閱讀摘要

    摘要:這時(shí)候控制臺(tái)看到的是對(duì)象的快照,然而點(diǎn)開看詳情的話是這段代碼在運(yùn)行的時(shí)候,瀏覽器可能會(huì)認(rèn)為需要把控制臺(tái)延遲到后臺(tái),這種情況下,等到瀏覽器控制臺(tái)輸出對(duì)象內(nèi)容時(shí),可能已經(jīng)運(yùn)行,因此會(huì)在點(diǎn)開的時(shí)候顯示,這是的異步化造成的。 本書屬于基礎(chǔ)類書籍,會(huì)有比較多的基礎(chǔ)知識(shí),所以這里僅記錄平常不怎么容易注意到的知識(shí)點(diǎn),不會(huì)全記,供大家和自己翻閱; 上中下三本的讀書筆記: 《你不知道的JavaScri...

    stackvoid 評(píng)論0 收藏0
  • 你不知道JS讀書筆記---作用域及閉包

    摘要:注此讀書筆記只記錄本人原先不太理解的內(nèi)容經(jīng)過閱讀你不知道的后的理解。作用域及閉包基礎(chǔ),代碼運(yùn)行的幕后工作者引擎及編譯器。 注:此讀書筆記只記錄本人原先不太理解的內(nèi)容經(jīng)過閱讀《你不知道的JS》后的理解。 作用域及閉包基礎(chǔ),JS代碼運(yùn)行的幕后工作者:引擎及編譯器。引擎負(fù)責(zé)JS程序的編譯及執(zhí)行,編譯器負(fù)責(zé)詞法分析和代碼生成。那么作用域就像一個(gè)容器,引擎及編譯器都從這里提取東西。 ...

    denson 評(píng)論0 收藏0
  • 你不知道JS讀書筆記之閉包在循環(huán)中應(yīng)用

    摘要:閉包在循環(huán)中的應(yīng)用延遲函數(shù)的回調(diào)會(huì)在循環(huán)結(jié)束時(shí)才執(zhí)行事實(shí)上,當(dāng)定時(shí)器運(yùn)行時(shí)即使沒給迭代中執(zhí)行的是多有的回調(diào)函數(shù)依然是在循環(huán)結(jié)束后才會(huì)被執(zhí)行,因此會(huì)每次輸出一個(gè)出來。 閉包在循環(huán)中的應(yīng)用 延遲函數(shù)的回調(diào)會(huì)在循環(huán)結(jié)束時(shí)才執(zhí)行;事實(shí)上,當(dāng)定時(shí)器運(yùn)行時(shí)即使沒給迭代中執(zhí)行的是 setTime(..., 0),多有的回調(diào)函數(shù)依然是在循環(huán)結(jié)束后才會(huì)被執(zhí)行,因此會(huì)每次輸出一個(gè)6出來。 for(var...

    weapon 評(píng)論0 收藏0
  • JS筆記

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。異步編程入門的全稱是前端經(jīng)典面試題從輸入到頁面加載發(fā)生了什么這是一篇開發(fā)的科普類文章,涉及到優(yōu)化等多個(gè)方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進(jìn)的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識(shí)之 HTTP 協(xié)議 詳細(xì)介紹 HTT...

    rottengeek 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<