最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript異步編程Promise模式的6個(gè)特性

 更新時(shí)間:2014年04月03日 09:21:26   作者:  
Promise說(shuō)起來(lái)是一個(gè)非常簡(jiǎn)單的概念,即使你沒(méi)有機(jī)會(huì)去使用它,很有可能你也了解過(guò)它。Promise是一個(gè)非常有價(jià)值的構(gòu)造器,能夠幫助你避免使用鑲套匿名方法,而使用更具有可讀性的方式組裝異步代碼。這里我們將介紹6個(gè)最簡(jiǎn)單的特性,希望對(duì)大家有幫助

在我們開(kāi)始正式介紹之前,我們想看看Javascript Promise的樣子:

復(fù)制代碼 代碼如下:

var p = new Promise(function(resolve, reject) {
  resolve("hello world");
});

p.then(function(str) {
  alert(str);
});

1. then()返回一個(gè)Forked Promise

以下兩段代碼有什么區(qū)別呢?

復(fù)制代碼 代碼如下:

// Exhibit A
var p = new Promise(/*...*/);
p.then(func1);
p.then(func2);

// Exhibit B
var p = new Promise(/*...*/);
p.then(func1)
.then(func2);

如果你認(rèn)真以上兩段代碼等同的話,那么Promises只不過(guò)是一個(gè)一維的回調(diào)函數(shù)數(shù)組。然而,其實(shí)不是這樣的。每一個(gè)then()調(diào)用都返回一個(gè)forked promise。因此,ExhibitA中,如果func1()拋出一個(gè)異常,func2()仍舊正常調(diào)用。

在ExhibitB中,如果func1()拋出一個(gè)錯(cuò)誤,fun2()將不會(huì)被調(diào)用,因?yàn)榈谝粋€(gè)調(diào)用返回了一個(gè)新的promise,這個(gè)在func1()中會(huì)被拒絕。結(jié)果是func2()被跳過(guò)。

總結(jié):promises可以被fork成多個(gè)路徑,類似復(fù)雜的流程圖。

2. Callback應(yīng)該傳遞結(jié)果

當(dāng)你運(yùn)行下面代碼的時(shí)候什么會(huì)得到警告提示呢?

復(fù)制代碼 代碼如下:

var p = new Promise(function(resolve, reject) {
  resolve("hello world");
});

p.then(function(str) {})
.then(function(str) {
  alert(str);
});

第二個(gè)then()中的alert沒(méi)有顯示任何內(nèi)容。這是因?yàn)榛卣{(diào)函數(shù),在promise的上下文中,因?yàn)榻Y(jié)果的變化并沒(méi)有回調(diào)函數(shù)。promise期望你的回調(diào)函數(shù)返回同樣的結(jié)果或者返回一個(gè)替換結(jié)果,然后被傳遞到下一個(gè)回調(diào)函數(shù)中。

類似使用adpater來(lái)變化結(jié)果,如下:

復(fù)制代碼 代碼如下:

var feetToMetres = function(ft) { return ft*12*0.0254 };

var p = new Promise(/*...*/);

p.then(feetToMetres)
.then(function(metres) {
  alert(metres);
});

3. 只有來(lái)自上一層的異??梢员徊蹲?/P>

這兩段代碼有什么區(qū)別?

復(fù)制代碼 代碼如下:

// Exhibit A
new Promise(function(resolve, reject) {
  resolve("hello world");
})
.then(
  function(str) {
    throw new Error("uh oh");
  },
  undefined
)
.then(
  undefined,
  function(error) {
    alert(error);
  }
);
 

// Exhibit B
new Promise(function(resolve, reject) {
  resolve("hello world");
})
.then(
  function(str) {
    throw new Error("uh oh");
  },
  function(error) {
    alert(error);
  }
);


在第一段代碼中,在第一個(gè)then()中的異常被拋出,將會(huì)被第二個(gè)then()捕捉,然后“uh oh”警告將會(huì)被觸發(fā)。這個(gè)遵循只有前一個(gè)層次的異常會(huì)被捕捉。

在第二段代碼中,回調(diào)函數(shù)和錯(cuò)誤回調(diào)函數(shù)是同一個(gè)層次,意味著當(dāng)異常在回調(diào)中拋出,將不會(huì)被捕捉。事實(shí)上,第二段代碼的錯(cuò)誤回調(diào)將只會(huì)在promise為拒絕狀態(tài)或者promise本身出錯(cuò)的情況下拋出

4. 錯(cuò)誤可以被恢復(fù)

在一個(gè)錯(cuò)誤回調(diào)函數(shù)中,如果你不重新拋出錯(cuò)誤,promise會(huì)假設(shè)你已經(jīng)從錯(cuò)誤中恢復(fù),并且反轉(zhuǎn)成為已解決狀態(tài)。在下一個(gè)例子中,"i'm saved" 將會(huì)被顯示,這是因?yàn)樵诘谝粋€(gè)then()中的錯(cuò)誤回調(diào)沒(méi)有重新拋出異常。

復(fù)制代碼 代碼如下:

var p = new Promise(function(resolve, reject) {
  reject(new Error("pebkac"));
});

p.then(
  undefined,
  function(error) { }
)
.then(
  function(str) {
    alert("I am saved!");
  },
  function(error) {
    alert("Bad computer!");
  }
);

Promise可以被看作洋蔥上的層次。每一個(gè)then()添加另外一個(gè)層次到洋蔥上。每一個(gè)層次代表了一個(gè)被處理的活動(dòng)。當(dāng)層次結(jié)束,結(jié)果被認(rèn)為已經(jīng)修復(fù)并且為下一個(gè)層次做好了準(zhǔn)備。

5. Promises可以被暫停

因?yàn)槟阋呀?jīng)準(zhǔn)備好了在一個(gè)then()方法中執(zhí)行,并不意味著你不能夠暫停并且提前運(yùn)行其他。 為了暫停目前的promise,或者讓它等待以便另外一個(gè)promise完成,簡(jiǎn)單在then()中返回另外一個(gè)promise。

復(fù)制代碼 代碼如下:

var p = new Promise(/*...*/);

p.then(function(str) {
  if(!loggedIn) {
    return new Promise(/*...*/);
  }
})
.then(function(str) {
  alert("Done.");
})

在前面代碼中,直到新的promise解析后提示才會(huì)出現(xiàn)。這是一個(gè)方便的方式在已存在的異步代碼路徑中來(lái)引入更多地依賴。例如,你可能發(fā)現(xiàn)用戶session已經(jīng)timeout,并且你可能希望在繼續(xù)前面的代碼路徑前初始化第二個(gè)登陸。

6. Resolved Promises并不會(huì)立刻執(zhí)行

運(yùn)行下面代碼會(huì)得到提示框么?

復(fù)制代碼 代碼如下:

function runme() {
  var i = 0;

  new Promise(function(resolve) {
    resolve();
  })
  .then(function() {
    i += 2;
  });
  alert(i);
}

因?yàn)閜romise被立刻解析,然后then()方法被立刻執(zhí)行,所以你可能會(huì)認(rèn)為會(huì)探出提示2。但是promise定義要求所有的調(diào)用都被強(qiáng)制異步。因此提示會(huì)在被修改前生成。

相關(guān)文章

  • 關(guān)于js注冊(cè)事件的常用方法

    關(guān)于js注冊(cè)事件的常用方法

    為了兼容各種瀏覽器,今天沒(méi)事特意復(fù)習(xí)了一下js原生事件特性,對(duì)其封裝一下。
    2013-04-04
  • 沒(méi)有document.getElementByName方法

    沒(méi)有document.getElementByName方法

    document.getElementByName方法沒(méi)有document.getElementsByName得到的是標(biāo)簽的數(shù)組,下面為大家詳細(xì)介紹下具體的使用,感興趣的朋友可以參考下,希望對(duì)大家有所幫助
    2013-08-08
  • 超實(shí)用的JavaScript表單代碼段

    超實(shí)用的JavaScript表單代碼段

    這篇文章主要為大家分享了超實(shí)用的JavaScript表單代碼段,幫助大家更好地學(xué)習(xí)使用javascript表單操作,感興趣的小伙伴們可以參考一下
    2016-02-02
  • js數(shù)值計(jì)算時(shí)使用parseInt進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換(jquery)

    js數(shù)值計(jì)算時(shí)使用parseInt進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換(jquery)

    這篇文章主要介紹了js數(shù)值計(jì)算時(shí)使用parseInt進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換(jquery),需要的朋友可以參考下
    2014-10-10
  • JavaScript中這6個(gè)新特性你都了解了嗎

    JavaScript中這6個(gè)新特性你都了解了嗎

    作為一門不斷演進(jìn)的語(yǔ)言,JavaScript每年都會(huì)引入新特性,這篇文章主要為大家整理了一些個(gè)人認(rèn)為特別有用的新JavaScript特性,以及一些補(bǔ)充的實(shí)例代碼,希望對(duì)大家有所幫助
    2024-01-01
  • javascript基本包裝類型介紹

    javascript基本包裝類型介紹

    這篇文章主要介紹了javascript的基本包裝類型,JS為了便于操作基本類型,提供了3個(gè)特殊的引用類型:Boolean/Number和String,需要的朋友可以參考下
    2015-04-04
  • JS如何實(shí)現(xiàn)文本框隨文本的長(zhǎng)度而增長(zhǎng)

    JS如何實(shí)現(xiàn)文本框隨文本的長(zhǎng)度而增長(zhǎng)

    這篇文章主要介紹了JS如何實(shí)現(xiàn)文本框隨文本的長(zhǎng)度而增長(zhǎng)的方法,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • JavaScript數(shù)組合并案例講解

    JavaScript數(shù)組合并案例講解

    這篇文章主要介紹了JavaScript數(shù)組合并案例講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • js運(yùn)算精度丟失的2個(gè)解決方法

    js運(yùn)算精度丟失的2個(gè)解決方法

    近期在做項(xiàng)目的時(shí)候,遇到了一些JS浮點(diǎn)數(shù)精度的問(wèn)題,這個(gè)問(wèn)題其實(shí)說(shuō)大不大,說(shuō)小不小,下面這篇文章主要給大家介紹了關(guān)于js運(yùn)算精度丟失的2個(gè)解決方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • Bootstrap基本組件學(xué)習(xí)筆記之導(dǎo)航(10)

    Bootstrap基本組件學(xué)習(xí)筆記之導(dǎo)航(10)

    這篇文章主要為大家詳細(xì)介紹了Bootstrap基本組件學(xué)習(xí)筆記之導(dǎo)航,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12

最新評(píng)論

瓮安县| 嘉定区| 资溪县| 道真| 沛县| 贞丰县| 贵州省| 措美县| 阳朔县| 清丰县| 吴桥县| 渑池县| 平远县| 广平县| 聂拉木县| 尤溪县| 蒲江县| 南京市| 泗洪县| 民丰县| 昌平区| 奉新县| 井研县| 安乡县| 丰县| 罗田县| 双流县| 沾化县| 彭泽县| 兴业县| 特克斯县| 富裕县| 镇赉县| 桦南县| 灌云县| 昌邑市| 濮阳市| 泉州市| 施秉县| 囊谦县| 宁都县|