国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

關于es6--promise

tommego / 2605人閱讀

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

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

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

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

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

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

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

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

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

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

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

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

function runAsync1(){
  var p = new Promise(function(resolve, reject){
    //做一些異步操作
    setTimeout(function(){
      console.log("異步任務1執行完成");
      resolve("隨便什么數據1");
    }, 1000);
  });
  return p;            
}
function runAsync2(){
  var p = new Promise(function(resolve, reject){
    //做一些異步操作
    setTimeout(function(){
      console.log("異步任務2執行完成");
      resolve("隨便什么數據2");
    }, 2000);
  });
  return p;           
  }
function runAsync3(){
  var p = new Promise(function(resolve, reject){
    //做一些異步操作
    setTimeout(function(){
      console.log("異步任務3執行完成");
      resolve("隨便什么數據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);
});

這樣能夠按順序,每隔兩秒輸出每個異步回調中的內容,在runAsync2中傳給resolve的數據,能在接下來的then方法中拿到。運行結果


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

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

結果如下:

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

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

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

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

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


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

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

效果和寫在then的第二個參數里面一樣。不過它還有另外一個作用:在執行resolve的回調(也就是上面then中的第一個參數)時,如果拋出異常了(代碼出錯了),那么并不會報錯卡死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的回調中,我們console.log(somedata);而somedata這個變量是沒有被定義的。如果我們不用Promise,代碼運行到這里就直接在控制臺報錯了,不往下運行了。但是在這里,會得到這樣的結果:


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

all的用法
Promise的all方法提供了并行執行異步操作的能力,并且在所有異步操作執行完后才執行回調。我們仍舊使用上面定義好的runAsync1、runAsync2、runAsync3這三個函數,看下面的例子:

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

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


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

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

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


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

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

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

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100849.html

相關文章

  • es6 - Promise

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

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

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

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

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

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

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

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

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

    Vicky 評論0 收藏0

發表評論

0條評論

tommego

|高級講師

TA的文章

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