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

資訊專欄INFORMATION COLUMN

你真的了解JavaScript的Promise嗎?

darkbaby123 / 973人閱讀

摘要:說(shuō)明狀態(tài)改變的調(diào)用是同步于的。如果在構(gòu)造函數(shù)的回調(diào)函數(shù)中或的回調(diào)函數(shù)中發(fā)生了異常,返回的會(huì)自動(dòng)。避免了發(fā)送重復(fù)的請(qǐng)求。

什么是Promise

Promise代理了一個(gè)可能要在未來(lái)才能到達(dá)的值[[PromiseValue]]。Promise的一個(gè)最重要的特點(diǎn)是,你可以通過(guò)then來(lái)指定當(dāng)[[PromiseValue]]到來(lái)時(shí)(或到來(lái)失敗時(shí))調(diào)用的handler

Promise的4種狀態(tài)

fulfilled - 成功,[[PromiseValue]]是成功獲取到的值

rejected - 失敗,[[PromiseValue]]是失敗的原因

pending - [[PromiseValue]]還沒(méi)有到達(dá)

settled - [[PromiseValue]]已經(jīng)有結(jié)果(fulfilled或rejected)

創(chuàng)建Promise 方式1:new Promise(executor)
new Promise( /* executor */ function(resolve, reject) { ... } );

傳入Promise()的參數(shù)叫做executor,它封裝了獲取[[PromiseValue]]的過(guò)程。

在初始化Promise的過(guò)程中,executor被Promise內(nèi)部代碼執(zhí)行,并給executor傳入2個(gè)參數(shù):resolve函數(shù), reject函數(shù)。

MDN文檔:The executor function is executed immediately by the Promise implementation, passing resolve and reject functions (the executor is called before the Promise constructor even returns the created object).

即使在executor中調(diào)用了resolve或reject,也會(huì)先執(zhí)行完當(dāng)前的executor函數(shù)體(不能像return一樣直接退出函數(shù)體)

var p1 = new Promise(function (res, rej) {
  console.log("before res");
  res("ok!");
  console.log("after res");
});
console.log("after p1 init, p1:", p1);

// before res
// after res  它被輸出說(shuō)明:即使在executor中調(diào)用了resolve或reject,也會(huì)先執(zhí)行完當(dāng)前的executor函數(shù)體,而不像return那樣立即退出函數(shù)
// after p1 init, p1: Promise { "ok!" } 它在"before/after res"以后才被輸出說(shuō)明:Promise在初始化過(guò)程中就會(huì)同步地調(diào)用executor(called synchronously)

executor的resolve或reject執(zhí)行以后,Promise的狀態(tài)就立刻改變(change synchronously)。

var p1 = new Promise(function (res, rej) {
  setImmediate(function() {
    res("haha");
    console.log("after res", p1); // executor的res函數(shù)執(zhí)行完畢以后,p1狀態(tài)已經(jīng)變?yōu)閒ulfilled
  });
});
console.log("after init", p1);  // 由于executor的res或rej函數(shù)還未執(zhí)行,p1處于pending狀態(tài)

// after init Promise {  }
// after res Promise { "haha" }

方式2:Promise.resolve(value)

Promise.resolve(value);

返回一個(gè)fulfilled的Promise,[[PromiseValue]]為value。

Promise.resolve(promise);

直接返回參數(shù)promise。

Promise.resolve(thenable);

將thenable轉(zhuǎn)換為Promise,Promise的狀態(tài)和[[PromiseValue]]跟隨thenable。thenable會(huì)在后文討論。

方式3:Promise.reject(reason)

返回一個(gè)rejected的Promise。
Promise.reject(reason)就是下面代碼的語(yǔ)法糖形式:

new Promise(function(resolve, reject){
    reject(reason);
});

它沒(méi)有Promise.resolve(something)這么復(fù)雜,不管傳入什么,它直接將參數(shù)reason作為reject原因,返回一個(gè)rejected Promise,即使你閑著沒(méi)事干傳一個(gè)Promise進(jìn)去:

var p = Promise.resolve("res");
Promise.reject(p)
    .then((val) => {
        console.log("111", val);
    }, (err) => {
        console.log("222", err === p);
    });
// 222 true
為了方便debug,最好傳入Error實(shí)例。
Promise的核心方法:then(onFulfilled[, onRejected]) 先說(shuō)說(shuō)then模式

then模式:你先把成功和失敗時(shí)要調(diào)用的handler傳給then函數(shù),等到時(shí)機(jī)成熟以后(進(jìn)入settled狀態(tài)以后),then函數(shù)就幫你調(diào)用合適的那個(gè)handler。存在一個(gè)這樣的then函數(shù)的對(duì)象叫做Thenable對(duì)象。

// 一個(gè)簡(jiǎn)單的Thenable對(duì)象
var thenable = {
  then: function (onFulfilled, onRejected) {
    // setTimeout模擬一個(gè)需要花2秒的異步過(guò)程
    setTimeout(function () {
      var num = Math.random();
      if (num > 0.5) {
        onFulfilled(num);
      } else {
        onRejected(num);
      }
    }, 2000);
  }
}
// 使用方式
thenable.then(
  function (result) {
    console.log("get result:", result);
  },
  function (err) {
    console.log("get error:", err);
  });
then模式類似于我們經(jīng)常使用的Callback模式。
說(shuō)回Promise的then方法

Promise的then方法其實(shí)就是在普通的then模式的基礎(chǔ)上增加了鏈?zhǔn)秸{(diào)用的功能:then函數(shù)返回Promise對(duì)象,前一個(gè)Promise對(duì)象進(jìn)入settled狀態(tài)以后才調(diào)用下一個(gè)then函數(shù)的handler。

Promise.prototype.then()涉及2個(gè)Promise對(duì)象:

調(diào)用then方法的Promise對(duì)象,這里用p1表示

調(diào)用then以后返回的Promise對(duì)象,這里用p2表示

p2 = p1.then(onFulfilled, onRejected);

then的作用就是,立即返回一個(gè)pending狀態(tài)的Promise:p2,并在p1進(jìn)入settled狀態(tài)以后自動(dòng)幫你調(diào)用handler

如果進(jìn)入fulfilled狀態(tài)(成功),自動(dòng)調(diào)用onFulfilled

如果進(jìn)入rejected狀態(tài)(失敗),自動(dòng)調(diào)用onRejected

在調(diào)用完handler以后,會(huì)根據(jù)handler的返回值觸發(fā)p2的狀態(tài)改變

如果handler返回一個(gè)普通值val,p2狀態(tài)立即(synchronously)變化:pending-->fulfilled,且p2的[[PromiseValue]]為val。

如果handler中throw一個(gè)錯(cuò)誤err,p2狀態(tài)立即(synchronously)變化:pending-->rejected,且p2的[[PromiseValue]]為err。

如果handler返回一個(gè)settled的Promise對(duì)象temp,p2狀態(tài)立即(synchronously)變化:pending-->與temp相同的狀態(tài),且p2的[[PromiseValue]]與temp的[[PromiseValue]]相同。

如果handler返回一個(gè)pending的Promise對(duì)象temp,p2的狀態(tài)不立即改變,而是等到temp進(jìn)入settled狀態(tài)以后,p2的狀態(tài)再(異步地)改變:pending-->與temp相同的狀態(tài),且p2的[[PromiseValue]]與temp的[[PromiseValue]]相同。

在這里我們只用關(guān)注p2是如何改變的,在后文我會(huì)解釋p2是什么時(shí)候改變的(同步還是異步)以及p2的handler是什么時(shí)候調(diào)用的。

舉個(gè)例子:

Promise.resolve("result").then(onFulfilled1, onRejected1).then(onFulfilled2, onRejected2);

這等價(jià)于:

var p1 = Promise.resolve("result");
var p2 = p1.then(onFulfilled1, onRejected1);
var p3 = p2.then(onFulfilled2, onRejected2);

因?yàn)閜1是fulfilled狀態(tài),所以p1的成功handler——onFulfilled1被調(diào)用。

如果onFulfilled1返回普通值(不是Promise),那么p2的狀態(tài)變化:pending-->fulfilled,且p2的[[PromiseValue]]為onFulfilled1的返回值。接下來(lái)p2的成功handler——onFulfilled2被調(diào)用,且傳入onFulfilled2的參數(shù)為p2的[[PromiseValue]]

如果onFulfilled1返回的是Promise,那么p2的狀態(tài)和[[PromiseValue]]都跟隨這個(gè)被返回的Promise。onFulfilled2將在p2 fulfilled以后被調(diào)用,onRejected2將在p2 rejected以后被調(diào)用,傳入的參數(shù)都是p2的[[PromiseValue]]。

依此類推,p3的狀態(tài)和[[PromiseValue]]都取決于onFulfilled2/onRejected2的返回值。

handler何時(shí)被調(diào)用

handler的調(diào)用異步于then的調(diào)用。

A異步于B的意思:A與B在JavaScript消息隊(duì)列中屬于不同的消息。當(dāng)前消息的調(diào)用棧完全退出以后,Event loop再處理下一個(gè)消息。Event loop處理完B消息以后可能要再處理0個(gè)或多個(gè)消息才能處理到A。

如果p1是通過(guò)new Promise(executor)的方式得到,那么除了滿足第一條以外,p1 handler的調(diào)用還異步于executor中resolve()reject()的調(diào)用。

如果Promise是由then返回的:

var p1 = Promise.resolve("haha");
var p2 = p1.then(p1_handler);
p2.then(p2_handler)

那么除了滿足第一條以外,如我在之前討論then的時(shí)候所說(shuō):

如果p1_handler產(chǎn)生同步的結(jié)果(包括返回普通值、拋出異常、返回settled Promise),則p2狀態(tài)立即變化,且p2_handler立即調(diào)用。這兩者都是同步于p1_handler進(jìn)行的。

如果p1_handler產(chǎn)生異步的結(jié)果(返回pending Promise,temp),則p2狀態(tài)隨著temp自動(dòng)改變,且p2_handler在p2狀態(tài)改變以后自動(dòng)調(diào)用。這兩者不僅異步于p1_handler進(jìn)行,而且異步于temp的狀態(tài)改變。

接下來(lái)我們一個(gè)一個(gè)地討論。

1. handler的調(diào)用異步于then的調(diào)用

在調(diào)用then為p1指定handler以后,并不會(huì)立即觸發(fā)handler的調(diào)用,而是向JavaScript消息隊(duì)列中增加一個(gè)消息,然后繼續(xù)執(zhí)行then之后的代碼。等到then所在的執(zhí)行棧完全彈出,Event loop再處理下一個(gè)消息。處理完若干個(gè)消息以后,Event loop處理到handler的消息。處理這個(gè)消息的時(shí)候,先檢查p1是否為settled,如果是,則調(diào)用對(duì)應(yīng)的handler。

即使p1在調(diào)用then時(shí)就是settled狀態(tài),handler的調(diào)用也是異步的。p1在調(diào)用then時(shí)是pending狀態(tài)的話就更不用說(shuō)了。

var p1 = Promise.resolve("haha");
// p1在調(diào)用then時(shí)就是settled狀態(tài)
p1.then((val) => {
  // 在nextTick以后,p1 handler才調(diào)用
  console.log("in p1 handler, p1:", p1);
});
console.log("after then called, p1:", p1);
process.nextTick(() => {
  console.log("nextTick, p1:", p1);
});

// after then called, p1: Promise { "haha" }
// nextTick, p1: Promise { "haha" }
// in p1 handler, p1: Promise { "haha" }

這也是為什么then返回的p2(在剛被返回的時(shí)候)必定處于pending狀態(tài)。因?yàn)閜1 handler的調(diào)用異步于p1的產(chǎn)生(也就異步于p2的產(chǎn)生)。p2需要等待p1 handler異步調(diào)用并返回結(jié)果才能改變狀態(tài),因此在handler被調(diào)用以前,p2都是pending狀態(tài):

var p1 = Promise.resolve("haha");
console.log("p1", p1);
var p2 = p1.then((val) => {
  console.log("in p1 handler");
  return "xixi";
});
console.log("p2", p2);
setImmediate(() => {
  console.log("setImmediate p2", p2);
});

// p1 Promise { "haha" }
// p2 Promise {  }
// in p1 handler
// setImmediate p2 Promise { "xixi" }
2. handler的調(diào)用異步于executor中resolve()、reject()的調(diào)用

如果p1是通過(guò)new Promise(executor)的方式得到,那么除了滿足第一條以外,p1 handler的調(diào)用還異步于executor中resolve()、reject()的調(diào)用。
也就是說(shuō)resolve()reject()的調(diào)用并不會(huì)立即觸發(fā)handler的調(diào)用,而是向JavaScript消息隊(duì)列中增加一個(gè)消息,等待Event loop處理到這個(gè)消息。處理這個(gè)消息的時(shí)候會(huì)調(diào)用handler。
例子(用node.js運(yùn)行):

var global_val = "old value";

var p1 = new Promise((res) => {
  setTimeout(function () {
    res("haha");
    console.log(p1); // p1的狀態(tài)立刻改變
    console.log("immediately", global_val); // 但是此時(shí)p1的handler還沒(méi)有調(diào)用
    process.nextTick(function () {
      console.log("nextTick", global_val);  // 此時(shí)p1的handler還是沒(méi)有調(diào)用
    });
    setImmediate(function() {
      console.log("setImmediate", global_val);  // 此時(shí)p1的handler已經(jīng)調(diào)用
    });
  }, 1000);
});
var p2 = p1.then(() => {
  // p1的handler
  console.log("in p1 handler");
  global_val = "new value";
});

// Promise { "haha" }
// immediately old value
// nextTick old value
// in p1 handler
// setImmediate new value
為什么handler要異步于executor的resolve()reject()調(diào)用

因?yàn)樵趀xecutor的resolve()、reject()的調(diào)用以后可能還有其他代碼要同步執(zhí)行(當(dāng)前handler還沒(méi)有結(jié)束)。前一個(gè)handler都還沒(méi)有執(zhí)行完,自然不應(yīng)該開(kāi)始下一個(gè)handler的執(zhí)行。(handler的執(zhí)行不應(yīng)該嵌套,而應(yīng)該串行)

比如在上面global_val的例子中,傳入setTimeout的函數(shù)就是一個(gè)handler,調(diào)用res("haha")的時(shí)候這個(gè)handler還有很多代碼要執(zhí)行。那么下一個(gè)handler(p1的handler)不應(yīng)該打斷這些代碼的執(zhí)行。

3. 如果Promise是由then返回的

如果Promise是由then返回的:

var p1 = Promise.resolve("haha");
var p2 = p1.then(p1_handler);
p2.then(p2_handler)

那么除了滿足第一條以外,如我在之前討論then的時(shí)候所說(shuō):

如果p1_handler產(chǎn)生同步的結(jié)果(包括返回普通值、拋出異常、返回settled Promise),則p2狀態(tài)立即變化,且p2_handler立即調(diào)用。這兩者都是同步于p1_handler進(jìn)行的。

如果p1_handler產(chǎn)生異步的結(jié)果(返回pending Promise,temp),則p2狀態(tài)隨著temp自動(dòng)改變,且p2_handler在p2狀態(tài)改變以后自動(dòng)調(diào)用。這兩者不僅異步于p1_handler進(jìn)行,而且異步于temp的狀態(tài)改變。

這里給出一個(gè)測(cè)試代碼供大家自行驗(yàn)證,注釋中有說(shuō)明,并且可以通過(guò)注釋/解注釋來(lái)修改p1 handler的返回結(jié)果。

// 如果p1_handler產(chǎn)生同步的結(jié)果(包括返回普通值、拋出異常、返回settled Promise),則p2狀態(tài)立即變化,且p2_handler立即調(diào)用。這兩者都是同步于p1_handler進(jìn)行的。
// 如果p1_handler產(chǎn)生異步的結(jié)果(返回pending Promise,temp),則p2狀態(tài)隨著temp自動(dòng)改變,且p2_handler在p2狀態(tài)改變以后自動(dòng)調(diào)用。這兩者不僅異步于p1_handler進(jìn)行,而且異步于temp的狀態(tài)改變。

var p1 = Promise.resolve("haha");

var p2 = p1.then((val) => {
    console.log("in p1 handler. p1:", p1, "p2", p2, "p3:", p3);
    process.nextTick(function () {
        // 當(dāng)p1 handler產(chǎn)生同步的結(jié)果時(shí),p2 handler在nextTick之前就被調(diào)用,且p2在nextTick時(shí)已經(jīng)settled。說(shuō)明p2狀態(tài)改變、p2 handler的調(diào)用是同步于p1 handler的。
        // 當(dāng)p1 handler產(chǎn)生異步的結(jié)果時(shí),p2 handler在nextTick之后才被調(diào)用,且p2在nextTick時(shí)依然pending。說(shuō)明p2狀態(tài)改變、p2 handler的調(diào)用是異步于p1 handler的。
        console.log("p1 handler nextTick. p1:", p1, "p2", p2, "p3:", p3);
    });

    // throw "err!";
    // return Promise.resolve("heihei");
    // return Promise.reject("heihei");
    // return new Promise(res => {     // temp Promise
    //     setTimeout(function () {
    //         res("heihei");
    //         process.nextTick(function () {
    //             // p2在nextTick時(shí)依然是pending,說(shuō)明p2的狀態(tài)改變異步于temp的狀態(tài)改變
    //             console.log("resolve nextTick. p1:", p1, "p2", p2, "p3:", p3);
    //         });
    //     }, 1000);
    // });
    return "heihei";
});

var p3 = p2.then(val => {
    console.log("in p2 success handler. p1:", p1, "p2", p2, "p3:", p3);
    return "xixi";
}, err => {
    console.log("in p2 error handler. p1:", p1, "p2", p2, "p3:", p3);
    return "hoho";
});

process.nextTick(function () {
    // 它先于"in p1 handler"輸出可以說(shuō)明handler是異步于then調(diào)用的
    console.log("after then called. p1:", p1, "p2", p2, "p3:", p3);
});
異常處理

Promise rejected 后,將跳至帶有拒絕回調(diào)的下一個(gè) then()(或具有相同功能的 catch())。如果有then(func1, func2),則 func1 或 func2 中的一個(gè)將被調(diào)用,而不可能二者均被調(diào)用。但如果是 then(func1).catch(func2),則有可能兩者均被調(diào)用(func1 rejected時(shí))。

asyncThing1().then(function() {
  return asyncThing2();
}).then(function() {
  return asyncThing3();
}).catch(function(err) {
  return asyncRecovery1();
}).then(function() {
  return asyncThing4();
}, function(err) {
  return asyncRecovery2();
}).catch(function(err) {
  console.log("Don"t worry about it");
}).then(function() {
  console.log("All done!");
})

藍(lán)線表示 fulfilled 的 promise 路徑,紅路表示 rejected 的 promise 路徑。

如果在promise構(gòu)造函數(shù)的回調(diào)函數(shù)中then的回調(diào)函數(shù)中發(fā)生了 JavaScript 異常(throw Errow),返回的promise會(huì)自動(dòng)reject。

var jsonPromise = new Promise(function(resolve, reject) {
  // JSON.parse throws an error if you feed it some
  // invalid JSON, so this implicitly rejects:
  resolve(JSON.parse("This ain"t JSON"));
});

jsonPromise.then(function(data) {
  // This never happens:
  console.log("It worked!", data);
}).catch(function(err) {
  // Instead, this happens:
  console.log("It failed!", err);
})
最佳實(shí)踐:緩存Promise——重復(fù)利用異步操作的結(jié)果
var storyPromise;

function getChapter(i) {
  storyPromise = storyPromise || getJSON("story.json");

  return storyPromise.then(function(story) {
    return getJSON(story.chapterUrls[i]);
  })
}

// and using it is simple:
getChapter(0).then(function(chapter) {
  console.log(chapter);
  return getChapter(1);
}).then(function(chapter) {
  console.log(chapter);
})

假設(shè)我們要分別獲取story的各個(gè)章節(jié)(用getChapter函數(shù)),每個(gè)章節(jié)所在的URL存儲(chǔ)在story.jsonchapterUrls數(shù)組中。
我們不需要每次要獲取章節(jié)的時(shí)候都先獲取一次story.json在拿到章節(jié)所在URL,更好的做法是:調(diào)用一次getJSON("story.json")就將這個(gè)Promise緩存到storyPromise中,將來(lái)需要請(qǐng)求story.json的時(shí)候只需要重復(fù)利用這個(gè)fulfilledstoryPromise。避免了發(fā)送重復(fù)的HTTP請(qǐng)求。

Promise一旦settled,[[PromiseValue]]不會(huì)再改變,我們可以將它看作一個(gè)定值,多次使用。
因?yàn)镻romise對(duì)象無(wú)法被外部改變(無(wú)論是意外地還是惡意地),我們可以安全地將這個(gè)對(duì)象交給其他庫(kù)使用,而不用擔(dān)心庫(kù)會(huì)修改到Promise的結(jié)果。
最佳實(shí)踐:一個(gè) Promise fulfilled 以后再執(zhí)行下一個(gè) Promise

除了手動(dòng)寫(xiě)then回調(diào)來(lái)依次執(zhí)行Promise以外,對(duì)于一個(gè)數(shù)組的任務(wù),我們可以利用array.reduce的循環(huán)來(lái)創(chuàng)建then回調(diào)

// Loop through our chapter urls
story.chapterUrls.reduce(function(sequence, chapterUrl) {
  // 上一個(gè)Promise fulfilled以后才執(zhí)行下一個(gè)getJSON
  // 從而保證每一個(gè)章節(jié)是順序請(qǐng)求的,從而在頁(yè)面中是順序顯示的
  return sequence.then(function() {
    return getJSON(chapterUrl);
  }).then(function(chapter) {
    addHtmlToPage(chapter.html);
  });
}, Promise.resolve())
參考資料

https://developers.google.com...

https://developer.mozilla.org...

http://liubin.org/promises-book/

Node 定時(shí)器詳解講述了process.nextTick()和Promise回調(diào)函數(shù)(microtask)的執(zhí)行順序。

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

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

相關(guān)文章

  • JavasScript重難點(diǎn)知識(shí)

    摘要:忍者級(jí)別的函數(shù)操作對(duì)于什么是匿名函數(shù),這里就不做過(guò)多介紹了。我們需要知道的是,對(duì)于而言,匿名函數(shù)是一個(gè)很重要且具有邏輯性的特性。通常,匿名函數(shù)的使用情況是創(chuàng)建一個(gè)供以后使用的函數(shù)。 JS 中的遞歸 遞歸, 遞歸基礎(chǔ), 斐波那契數(shù)列, 使用遞歸方式深拷貝, 自定義事件添加 這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機(jī)制,如果...

    forsigner 評(píng)論0 收藏0
  • ES6-7

    摘要:的翻譯文檔由的維護(hù)很多人說(shuō),阮老師已經(jīng)有一本關(guān)于的書(shū)了入門,覺(jué)得看看這本書(shū)就足夠了。前端的異步解決方案之和異步編程模式在前端開(kāi)發(fā)過(guò)程中,顯得越來(lái)越重要。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(shū)(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會(huì)promise...... 本書(shū)的目的是以目前還在制定中的ECMASc...

    mudiyouyou 評(píng)論0 收藏0
  • 會(huì)用 Babel ?

    摘要:安裝然后在的配置文件加入入口文件引入這樣就可以啦,還是可以減少很多代碼量的。是參數(shù),等同于執(zhí)行正常。這個(gè)包很簡(jiǎn)單,就是引用了和,然后生產(chǎn)環(huán)境把它們編譯到目錄下,做了映射,供使用。 引入 這個(gè)問(wèn)題是對(duì)自己的發(fā)問(wèn),但我相信會(huì)有很多跟我一樣的同學(xué)。對(duì)于 babel 的使用,近半年來(lái)一直停留在與 webpack 結(jié)合使用,以及在瀏覽器開(kāi)發(fā)環(huán)境下。導(dǎo)致很多 babel 的包,我都不清楚他們是干嘛...

    mochixuan 評(píng)論0 收藏0
  • 2019前端工程師自檢清單與思考

    摘要:前端工程師自檢清單對(duì)于,掌握其語(yǔ)法和特性是最基本的,但是這些只是應(yīng)用能力,最終仍舊考量仍然是計(jì)算機(jī)體系的理論知識(shí),所以數(shù)據(jù)結(jié)構(gòu),算法,軟件工程,設(shè)計(jì)模式等基礎(chǔ)知識(shí)對(duì)前端工程師同樣重要,這些知識(shí)的理解程度,可以決定你在前端工程師這條路上能走多 2019前端工程師自檢清單 對(duì)于JavaScript,掌握其語(yǔ)法和特性是最基本的,但是這些只是應(yīng)用能力,最終仍舊考量仍然是計(jì)算機(jī)體系的理論知識(shí),所...

    Honwhy 評(píng)論0 收藏0
  • [譯] 深入理解 Promise 五部曲:3. 可靠性問(wèn)題

    摘要:簡(jiǎn)單的說(shuō),即將到來(lái)的標(biāo)準(zhǔn)指出是一個(gè),所以作為一個(gè),必須可以被子類化。保護(hù)還是子類化這是個(gè)問(wèn)題我真的希望我能創(chuàng)建一個(gè)忠實(shí)的給及以下。 原文地址:http://blog.getify.com/promis... 如果你需要趕上我們關(guān)于Promise的進(jìn)度,可以看看這個(gè)系列前兩篇文章深入理解Promise五部曲--1.異步問(wèn)題和深入理解Promise五部曲--2.控制權(quán)轉(zhuǎn)移問(wèn)題。 Promi...

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

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

0條評(píng)論

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