亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

關于es6--promise

tommego / 2659人閱讀

摘要:就算改變已經(jīng)發(fā)生了,你再對對象添加回調(diào)函數(shù),也會立即得到這個結果。有了對象,就可以將異步操作以同步操作的流程表達出來,避免了層層嵌套的回調(diào)函數(shù)。但是在這里,會得到這樣的結果關于是用于指定發(fā)生錯誤時的回調(diào)函數(shù)。

看了很多關于promise的文章,此篇文章做以總結。
由于Javascript是一種單線程的語言,所有的代碼必須按照所謂的“自上而下”的順序來執(zhí)行。本特性帶來的問題就是,一些將來的、未知的操作,必須異步實現(xiàn)。promise就是一個比較常見的異步解決方案。

Promise有以下兩個特點:
(1)狀態(tài)不受外界影響。Promise對象代表一個異步操作,有三種狀態(tài):Pending(進行中)、Resolved(已完成,又稱 Fulfilled)和Rejected(已失?。?。只有異步操作的結果,可以決定當前是哪一種狀態(tài),任何其他操作都無法改變這個狀態(tài)。這也是Promise這個名字的由來,它的英語意思就是“承諾”,表示其他手段無法改變。
(2)一旦狀態(tài)改變,就不會再變,任何時候都可以得到這個結果。Promise對象的狀態(tài)改變,只有兩種可能:從Pending變?yōu)镽esolved和從Pending變?yōu)镽ejected。只要這兩種情況發(fā)生,狀態(tài)就凝固了,不會再變了,會一直保持這個結果。就算改變已經(jīng)發(fā)生了,你再對Promise對象添加回調(diào)函數(shù),也會立即得到這個結果。這與事件(Event)完全不同,事件的特點是,如果你錯過了它,再去監(jiān)聽,是得不到結果的。
有了Promise對象,就可以將異步操作以同步操作的流程表達出來,避免了層層嵌套的回調(diào)函數(shù)。此外,Promise對象提供統(tǒng)一的接口,使得控制異步操作更加容易。

首先,看一個例子,new一個promise

var p = new Promise(function(resolve, reject){
  //做一些異步操作
  setTimeout(function(){
    console.log("執(zhí)行完成");
    resolve("成功的數(shù)據(jù)");
  }, 2000);
});

Promise的構造函數(shù)接收一個參數(shù),是函數(shù),并且傳入兩個參數(shù):resolve,reject,分別表示異步操作執(zhí)行成功后的回調(diào)函數(shù)和異步操作執(zhí)行失敗后的回調(diào)函數(shù),按照標準來講,resolve是將Promise的狀態(tài)置為fullfiled,reject是將Promise的狀態(tài)置為rejected。

在上面的代碼中,我們執(zhí)行了一個異步操作,也就是setTimeout,2秒后,輸出“執(zhí)行完成”,并且調(diào)用resolve方法。

運行代碼,會在2秒后輸出“執(zhí)行完成”。注意!我只是new了一個對象,并沒有調(diào)用它,我們傳進去的函數(shù)就已經(jīng)執(zhí)行了,這是需要注意的一個細節(jié)。所以我們用Promise的時候一般是包在一個函數(shù)中,在需要的時候去運行這個函數(shù),如:

function runAsync(){
  var p = new Promise(function(resolve, reject){
    //做一些異步操作
    setTimeout(function(){
        console.log("執(zhí)行完成");
        resolve("隨便什么數(shù)據(jù)");
    }, 2000);
  });
  return p;            
}
runAsync()

在上面的代碼中,我們包裝好的函數(shù)最后會return一個promise對象,也就是說promise是一個對象,接下來就是promise的一些方法了:then/ catch /all/ race等
首先了解一下沒有promise的回調(diào)地獄

setTimeout(function(){
  left(function(){
    setTimeout(function(){
      left(function(){
        setTimeout(function(){
          left();
        },2000);
      });
    }, 2000);
  });
}, 2000);

以上代碼就是傳說中的回調(diào)地獄,如果有多層業(yè)務邏輯嵌套的話,不僅會使代碼閱讀困難,而且后面維護起來也是難點。
之后在ES6,Promise就應運而生。
用then來進行回調(diào)操作(鏈式操作)

function runAsync1(){
  var p = new Promise(function(resolve, reject){
    //做一些異步操作
    setTimeout(function(){
      console.log("異步任務1執(zhí)行完成");
      resolve("隨便什么數(shù)據(jù)1");
    }, 1000);
  });
  return p;            
}
function runAsync2(){
  var p = new Promise(function(resolve, reject){
    //做一些異步操作
    setTimeout(function(){
      console.log("異步任務2執(zhí)行完成");
      resolve("隨便什么數(shù)據(jù)2");
    }, 2000);
  });
  return p;           
  }
function runAsync3(){
  var p = new Promise(function(resolve, reject){
    //做一些異步操作
    setTimeout(function(){
      console.log("異步任務3執(zhí)行完成");
      resolve("隨便什么數(shù)據(jù)3");
    }, 2000);
  });
  return p;            
}
runAsync1()
.then(function(data){
  console.log(data);
  return runAsync2();
})
.then(function(data){
  console.log(data);
  return runAsync3();
})
.then(function(data){
  console.log(data);
});

這樣能夠按順序,每隔兩秒輸出每個異步回調(diào)中的內(nèi)容,在runAsync2中傳給resolve的數(shù)據(jù),能在接下來的then方法中拿到。運行結果


在then方法中,你也可以直接return數(shù)據(jù)而不是Promise對象,在后面的then中就可以接收到數(shù)據(jù)了,比如我們把上面的代碼修改成這樣:

runAsync1()
.then(function(data){
  console.log(data);
  return runAsync2();
})
.then(function(data){
  console.log(data);
  return "直接返回數(shù)據(jù)";  //這里直接返回數(shù)據(jù)
})
.then(function(data){
  console.log(data);
});

結果如下:

接下來說一下reject的用法:
reject的作用就是把Promise的狀態(tài)置為rejected,這樣我們在then中就能捕捉到,然后執(zhí)行“失敗”情況的回調(diào)??聪旅娴拇a。

function getNumber(){
  var p = new Promise(function(resolve, reject){
    //做一些異步操作
    setTimeout(function(){
      var num = Math.ceil(Math.random()*10); //生成1-10的隨機數(shù)
      if(num<=5){
        resolve(num);
      }
      else{
        reject("數(shù)字太大了");
      }
    }, 2000);
  });
  return p;            
}

getNumber()
.then(
    function(data){
      console.log("resolved");
      console.log(data);
    }, 
    function(reason, data){
      console.log("rejected");
      console.log(reason);
    }
);

getNumber函數(shù)用來異步獲取一個數(shù)字,2秒后執(zhí)行完成,如果數(shù)字小于等于5,我們認為是“成功”了,調(diào)用resolve修改Promise的狀態(tài)。否則我們認為是“失敗”了,調(diào)用reject并傳遞一個參數(shù),作為失敗的原因。

運行getNumber并且在then中傳了兩個參數(shù),then方法可以接受兩個參數(shù),第一個對應resolve的回調(diào),第二個對應reject的回調(diào)。所以我們能夠分別拿到他們傳過來的數(shù)據(jù)。多次運行這段代碼,你會隨機得到下面兩種結果:


注意,Promise.reject()方法的參數(shù),會原封不動地作為reject的理由,變成后續(xù)方法的參數(shù)。這一點與Promise.resolve方法不一致。
catch方法
catch的用法和then的第二個參數(shù)一樣,用來指定reject的回調(diào)

getNumber()
.then(function(data){
  console.log("resolved");
  console.log(data);
})
.catch(function(reason){
  console.log("rejected");
  console.log(reason);
});

效果和寫在then的第二個參數(shù)里面一樣。不過它還有另外一個作用:在執(zhí)行resolve的回調(diào)(也就是上面then中的第一個參數(shù))時,如果拋出異常了(代碼出錯了),那么并不會報錯卡死js,而是會進到這個catch方法中。請看下面的代碼:

getNumber()
.then(function(data){
  console.log("resolved");
  console.log(data);
  console.log(somedata); //此處的somedata未定義
})
.catch(function(reason){
  console.log("rejected");
  console.log(reason);
});

在resolve的回調(diào)中,我們console.log(somedata);而somedata這個變量是沒有被定義的。如果我們不用Promise,代碼運行到這里就直接在控制臺報錯了,不往下運行了。但是在這里,會得到這樣的結果:


關于catch
1.catch是用于指定發(fā)生錯誤時的回調(diào)函數(shù)。(建議不要在then的第二個參數(shù)寫rejected狀態(tài),總是使用catch)
2.catch()使回調(diào)報錯時不會卡死js而是會繼續(xù)往下執(zhí)行。
3.Promise 對象的錯誤具有“冒泡”性質(zhì),會一直向后傳遞,直到被捕獲為止。也就是說,錯誤總是會被下一個catch語句捕獲。
這里要注意,不管是then或者catch返回的都是一個新的Promise實例!而每個Primise實例都有最原始的Pending(進行中)到Resolve(已完成),或者Pending(進行中)到Reject(已失?。┑倪^程。

all的用法
Promise的all方法提供了并行執(zhí)行異步操作的能力,并且在所有異步操作執(zhí)行完后才執(zhí)行回調(diào)。我們?nèi)耘f使用上面定義好的runAsync1、runAsync2、runAsync3這三個函數(shù),看下面的例子:

Promise
.all([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
  console.log(results);
});

用Promise.all來執(zhí)行,all接收一個數(shù)組參數(shù),里面的值最終都算返回Promise對象。這樣,三個異步操作的并行執(zhí)行的,等到它們都執(zhí)行完后才會進到then里面。那么,三個異步操作返回的數(shù)據(jù)哪里去了呢?都在then里面呢,all會把所有異步操作的結果放進一個數(shù)組中傳給then,就是上面的results。所以上面代碼的輸出結果就是:「誰跑的慢,以誰為準執(zhí)行回調(diào)」


有了all,你就可以并行執(zhí)行多個異步操作,并且在一個回調(diào)中處理所有的返回數(shù)據(jù),有一個場景是很適合用這個的,一些游戲類的素材比較多的應用,打開網(wǎng)頁時,預先加載需要用到的各種資源如圖片、flash以及各種靜態(tài)文件。所有的都加載完后,我們再進行頁面的初始化。(個人感覺很想&&符號鏈接)
race的用法
all方法的效果實際上是「誰跑的慢,以誰為準執(zhí)行回調(diào)」,那么相對的就有另一個方法「誰跑的快,以誰為準執(zhí)行回調(diào)」,這就是race方法,這個詞本來就是賽跑的意思。race的用法與all一樣,我們把上面runAsync1的延時改為1秒來看一下:

Promise
.race([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
  console.log(results);
});

這三個異步操作同樣是并行執(zhí)行的。結果你應該可以猜到,1秒后runAsync1已經(jīng)執(zhí)行完了,此時then里面的就執(zhí)行了。結果是這樣的:


在then里面的回調(diào)開始執(zhí)行時,runAsync2()和runAsync3()并沒有停止,仍舊再執(zhí)行。于是再過1秒后,輸出了他們結束的標志,resolve/reject一旦輸出不會改變。(感覺就是||符號操作~~~)

還有一些關于promise的面試題。感興趣的可以看一下:https://mp.weixin.qq.com/s/Wv...
以上感謝:王漢炎 枸杞辣條 IT平頭哥聯(lián)盟

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

轉載請注明本文地址:http://www.ezyhdfw.cn/yun/100849.html

相關文章

  • es6 - Promise

    摘要:所謂異步編程中的異步是相對于同步的概念的。是一系列異步編程規(guī)范的統(tǒng)稱。如果中的回調(diào)函數(shù)返回一個值,那么返回的將會成為接受狀態(tài),并且將返回的值作為接受狀態(tài)的回調(diào)函數(shù)的參數(shù)值。參考介紹基礎篇深入理解與異步編程。 es6 promise與異步編程 對于一些還不具備大量編程經(jīng)驗的朋友來說,promise可能是es6比較難以掌握的點。首先是很多名詞,比如Promises,es6 Promise,...

    wemallshop 評論0 收藏0
  • ES6 Promise:模式與反模式

    摘要:盡管可以讓代碼更加簡潔易讀,但對于只熟悉回調(diào)函數(shù)的人來說,可能對此還是會有所懷疑。始終避免在或使用回調(diào)函數(shù),否則會吞噬任何后續(xù)的錯誤,將其作為鏈的一部分。然而,使用回調(diào)函數(shù),使用所謂的,即第一個參數(shù)是一個錯誤回調(diào)變得很常見。 原文:ES6 Promises: Patterns and Anti-Patterns作者:Bobby Brennan 當幾年前,第一次使用 NodeJS 的時候...

    djfml 評論0 收藏0
  • 通過 ES6 Promise 和 jQuery Deferred 的異同學習 Promise

    摘要:和和都有和,但是略有不同。實際上返回的是一個對象。和添加的回調(diào),添加的回調(diào)。所以在調(diào)用成功的情況下執(zhí)行添加的回調(diào),調(diào)用失敗時執(zhí)行添加的回調(diào)。,產(chǎn)生對象并,產(chǎn)生對象并,然后繼續(xù)處理,的語法糖,和的差不多但不同。 Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同。不過它們的作用可以簡單的用兩句話來描述 Deffere...

    Yujiaao 評論0 收藏0
  • ES6 Promise——then與catch的返回值實踐

    摘要:值的情況返回的會成為狀態(tài)。再次重復這一句話為的語法糖,它是的別名。也就是說,也是,它用于捕獲錯誤,它的參數(shù)也就是是的第二個參數(shù)。所以,假設中如果值的話,新的對象也會是接受狀態(tài)。 以下是在學習Promise關于catch與then的疑惑總結 一.catch為then的語法糖 故then方法與catch方法均會返回一個Promise對象(對,即使return 為某個值,或者throw er...

    omgdog 評論0 收藏0
  • 學習 Promise,掌握未來世界 JS 異步編程基礎

    摘要:構造函數(shù)規(guī)定,對象是一個構造函數(shù),用來生成實例。如果中的回調(diào)函數(shù)拋出一個錯誤,那么返回的將會成為拒絕狀態(tài),并且將拋出的錯誤作為拒絕狀態(tài)的回調(diào)函數(shù)的參數(shù)值。 其實想寫 Promise 的使用已經(jīng)很長時間了。一個是在實際編碼的過程中經(jīng)常用到,一個是確實有時候小伙伴們在使用時也會遇到一些問題。Promise 也確實是 ES6 中 對于寫 JS 的方式,有著真正最大影響的 API 特性之一。本...

    Vicky 評論0 收藏0

發(fā)表評論

0條評論

tommego

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<