中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

在javascript中使用promise時需要注意哪些事項

發布時間:2021-01-15 14:48:43 來源:億速云 閱讀:133 作者:Leah 欄目:開發技術

這期內容當中小編將會給大家帶來有關在javascript中使用promise時需要注意哪些事項,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

一、promise描述

promise是javascript中標準的內置對象,用于表示一個異步操作的最終狀態(是失敗還是成功完成)及其結果值。它讓你能夠把異步操作最終成功或者失敗的原因和響應的處理程序相關聯,也就是說通過promise你可以自定義異步操作結束后該做什么。這樣的話異步方法就和同步方法很類似,也有返回值,只不過這個返回值不是立即返回最終的值,而是返回一個promise,當promise的狀態發生改變時,就會觸發相應的處理程序。

一個promise無論什么時候都必然處于以下幾種狀態:1、待定(pending) 2、已兌現(fulfilled) 3、已拒絕(rejected)

promise創建之初是待定狀態,它既咩有被兌現也咩有被拒絕,它用于包裝還沒有被添加promise支持的函數,包裝后的函數變成異步操作函數,當操作結束時,會有兩個兩個分支,一個是已兌現,一個是已拒絕,如下圖。已兌現狀態的promise會調用后續的then方法,而已拒絕狀態的promise既可以調用then方法,也可以被catch方法捕捉到。為什么then方法可以捕捉兩個狀態的promise呢?這里先不講,下面再詳細介紹。

在javascript中使用promise時需要注意哪些事項

二、promise 的流程走向

上圖是promise的流程圖,從左到右可以得知一個promise在待定狀態時通過兩個分支走向分別進入then方法或者catch方法,這兩個c方法都會返回promise,如果這個promise也被敲定了,而且其后也有then方法或者catch方法,則又會進入后續的then和catch中,直至咪有。

也就是說,promise和then或者catch可以形成一個異步操作的鏈式結構,結合js的事件循環機制,這使得js的優勢更加明顯,發展至今仍能在瀏覽器上頻繁看到它的身影。

我們要注意流程的特點:

1、promise是對象,它的轉移成功不取決于返回值,而取決于狀態的敲定(是成功還是失敗)

2、then和catch是函數,只要有promise狀態發生了改變,該promise對應后面的then或者catch方法就會被調用,而這兩個方法本身會返回一個promise,這個返回的promise又會影響這兩個方法后面的then或者catch方法。兩個方法的返回值一定是promise。

三、promise的創建

Promise對象是由關鍵字new及其構造函數來創建的。該構造函數會把一個叫做“處理器函數”(executor function)的函數作為它的參數。這個“處理器函數”接受兩個函數——resolvereject——作為其參數。當異步任務順利完成且返回結果值時,會調用resolve函數;而當異步任務失敗且返回失敗原因(通常是一個錯誤對象)時,會調用reject函數。示例如下:

let myFirstPromise = new Promise(function(resolve, reject){
 //當異步代碼執行成功時,我們才會調用resolve(...), 當異步代碼失敗時就會調用reject(...)
 //在本例中,我們使用setTimeout(...)來模擬異步代碼,實際編碼時可能是XHR請求或是HTML5的一些API方法.
 setTimeout(function(){
  resolve("成功!"); //代碼正常執行!
 }, 250);
});

myFirstPromise.then(function(successMessage){
 //successMessage的值是上面調用resolve(...)方法傳入的值.
 //successMessage參數不一定非要是字符串類型,這里只是舉個例子
 console.log("Yay! " + successMessage);
});

四、promise的優勢

在promise未出現時,如果我們調用異步代碼塊的話是沒有辦法保持順序的,而如果又出現了異步代碼結果之間按序的需求,該如何實現呢?

以前的話通常都會將異步代碼一層一層地內嵌來實現異步代碼按序實現,但是這就造成了代碼維護困難,開發難度增大

doSomething(function(result) {
 doSomethingElse(result, function(newResult) {
 doThirdThing(newResult, function(finalResult) {
  console.log('Got the final result: ' + finalResult);
 }, failureCallback);
 }, failureCallback);
}, failureCallback);

這就是經典的回調地獄。而如果使用了前面介紹的promise,那么代碼就變成了容易維護的鏈式結構

五、then方法返回的promise類型

當一個Promise完成(fulfilled)或者失敗(rejected)時,返回函數將被異步調用(由當前的線程循環來調度完成)。具體的返回值依據以下規則返回。如果then中的回調函數:

  • 返回了一個值,那么then返回的 Promise 將會成為接受狀態,并且將返回的值作為接受狀態的回調函數的參數值。

  • 沒有返回任何值,那么then返回的 Promise 將會成為接受狀態,并且該接受狀態的回調函數的參數值為undefined

  • 拋出一個錯誤,那么then返回的 Promise 將會成為拒絕狀態,并且將拋出的錯誤作為拒絕狀態的回調函數的參數值。

  • 返回一個已經是接受狀態的 Promise,那么then返回的 Promise 也會成為接受狀態,并且將那個 Promise 的接受狀態的回調函數的參數值作為該被返回的Promise的接受狀態回調函數的參數值。

  • 返回一個已經是拒絕狀態的 Promise,那么then返回的 Promise 也會成為拒絕狀態,并且將那個 Promise 的拒絕狀態的回調函數的參數值作為該被返回的Promise的拒絕狀態回調函數的參數值。

  • 返回一個未定狀態(pending)的 Promise,那么then返回 Promise 的狀態也是未定的,并且它的終態與那個 Promise 的終態相同;同時,它變為終態時調用的回調函數參數與那個 Promise 變為終態時的回調函數的參數是相同的。

六、catch捕捉的錯誤

catch能捕捉promise組合中出現的錯誤,但是有兩種錯誤不能捕捉:

1、已決議的錯誤不能捕捉

//創建一個新的 Promise ,且已決議
var p1 = Promise.resolve("calling next");

var p2 = p1.catch(function (reason) {
 //這個方法永遠不會調用
 console.log("catch p1!");
 console.log(reason);
});

p2.then(function (value) {
 console.log("next promise's onFulfilled"); /* next promise's onFulfilled */
 console.log(value); /* calling next */
}, function (reason) {
 console.log("next promise's onRejected");
 console.log(reason);
});

2、異步函數中拋出的錯誤不能捕捉

需要注意的是,作者親手實踐發現:promise包裹的異步函數執行成功后必須顯式地調用resolve和reject方法才能觸發后續then和catch方法,如果promise方法包裹的不是異步函數,是普通的同步函數,如果該同步代碼運行出錯,即便沒有調用reject方法時,后面的catch方法仍然能夠捕捉到這個錯誤,但如果同步代碼沒有出錯,沒有顯式調用resolve方法轉移的話,后續的then方法不會觸發。

七、高級示例

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
 <style>
  *{
   margin: 10px;
  }
  html{
   width: 100%;
   height: 100%;
  }
  body{
   width: 100%;
   height: 100%;
   display:flex;
   align-items: center;
   justify-content: center;
  }
  div.displaydatabox{
   width: 300px;
   height: 300px;
   border-radius: 50px;
   text-align: center;
   line-height: 300px;
   box-shadow: 0 0 10px 2px black;
  }
  div.button{
   width: 100px;
   height: 50px;
   border-radius: 21px;
   border: 2px solid orange;
   line-height: 50px;
   text-align: center;
   cursor: pointer;
  }
 </style>
</head>
<body>
 <div class="button">創建</div>
 <div class="button">輸入文字</div>
 <div class="button">消失</div>
 <script lang="javascript">
  let buttonlist=document.querySelectorAll("div.button");
  let body=document.querySelector("body");
  buttonlist[0].onclick=function()
  {
   let div=document.createElement("div");
   div.className="displaydatabox";
   body.appendChild(div);
  }
  buttonlist[2].onclick=function()
  {
   let div=document.querySelector("div.displaydatabox");
   body.removeChild(div);
  }
  buttonlist[1].onclick=function(e)
  {
   let p1=new Promise((resolve,reject)=>
   {
    setTimeout(()=>{//用setTimeout函數模擬異步函數
     let div=document.querySelector("div.displaydatabox");
     div.textContent="這是promise實驗";
     //reject(1);
     resolve(1);//調用resolve將調用第一個then
    },2000);
   }).then(function(resolve){
    return new Promise((resolve,reject)=>{
     console.log("這是狀態咩有敲定的promise,所以不會調用后面所有的then方法");            //resolve(1)//沒有調用resolve或者reject,所以狀態未敲定。如果調用,將輸出1和finally it has been called!!
    })
   .then(function(e){
    console.log(e);
   });
   }).catch(function(e)
   {
    console.log(e+" 沒有塊可以輸入!!");
   }).then(()=>
   {
    console.log("finally it has been called!!");
   })
  }
 </script>
</body>
</html>

上述就是小編為大家分享的在javascript中使用promise時需要注意哪些事項了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

凤凰县| 东莞市| 准格尔旗| 和林格尔县| 桐柏县| 玉山县| 安西县| 乐昌市| 梁山县| 石林| 龙口市| 咸阳市| 永泰县| 论坛| 宁阳县| 岳阳市| 太保市| 新巴尔虎左旗| 满城县| 泗洪县| 五河县| 田东县| 灵璧县| 郯城县| 海安县| 五大连池市| 威海市| 漯河市| 建宁县| 乌拉特后旗| 桐庐县| 扎赉特旗| 麟游县| 寿光市| 昌都县| 旌德县| 鄂温| 高尔夫| 义乌市| 乐都县| 福州市|