一文入門Promise,詳細介紹Promise的用法

2020-10-28 15:00:55

PromiseES6引入的語法,專門處理非同步程式設計

promise 基本用法

  • 範例化Promise物件,建構函式中傳遞函數,該函數中用於處理非同步任務
  • resolve和reject兩個引數用於處理成功和失敗兩種情況,並通過p.then獲取處理結果

例如如下程式碼:

var p = new Promise(function (resolve,reject){
  //這裡開一個定時器模仿非同步任務
     setTimeout(function(){
          var flag = turn;
          if(flag) {
          //正常情況下拿到資料
          resolve('我是成功時的返回資料');
          } else {
          //伺服器出錯,響應的錯誤資訊
          reject('出錯了');
          }
      },1000);
 });
 p.then(function(data) {
 //在這裡用data接收正確資訊
     console.log(data);
 },function(info) {
 //在這裡用info接收錯誤資料
     console.log(info);
  });

Promise 處理原生Ajax

//基於Promise傳送Ajax請求
function queryData(url) {
   var p = new Promise(function(resolve,reject) {
         var xhr =  new XMLHttpRequest();
         //每當 readyState 改變時,就會觸發 onreadystatechange 事件
         xhr.onreadystatechange =function() {
             if(xhr.readyState != 4) return;
             if(xhr.readyState === 4 && xhr.status  ===200) {
                resolve(xhr.responseText);//拿到響應資料(以文字形式)
             } else {
                reject('伺服器錯誤');
              }
          };
          xhr.open('get',url);
          xhr.send(null);
          });
          return p;
    }
    queryData('http://localhost:3000/data')
        .then(function(data) {
           console.log(data);//列印正確的響應資料
         },function(info) {
           console.log(info)//列印錯誤資訊
         });

readyState狀態碼和HTTP狀態碼在這裡插入圖片描述

onload

進入onload之後,只出現了狀態碼4。也就是說,只有處於狀態碼4,請求已完成,響應已就緒的情況下,才會進入onload。只要進入onload請求中,一定是已經到4這個狀態了。

function loadText(){
            let xhr = new XMLHttpRequest();
            xhr.open('GET','sample.txt',true);
            console.log("READYSTATE"+ xhr.readyState);
            //兩種請求方式onload和onreadystatechange
            xhr.onload = function(){
                console.log("READYSTATE"+ xhr.readyState);
                console.log(this.responseText);
            }
            xhr.send();
}

onreadystatechange 事件

當請求被傳送到伺服器時,我們需要執行一些基於響應的任務。
每當 readyState 改變時,就會觸發 onreadystatechange 事件。
readyState 屬性存有 XMLHttpRequest 的狀態資訊。

以下是 XMLHttpRequest 物件的三個重要的屬性:
在這裡插入圖片描述
在 onreadystatechange 事件中,我們規定當伺服器響應已做好被處理的準備時所執行的任務。
當 readyState 等於 4 且狀態為 200 時,表示響應已就緒:

//注意:onreadystatechange 事件被觸發 5 次(0 - 4),對應著 readyState 的每個變化。
xhr.open("get","test1.php",true);
xhr.send(null);
xhr.onreadystatechange = function(){ // 回撥函數
		if(xhr.readyState == 4){
			if(xhr.status == 200){
				var data = xhr.responseText; // 獲取響應資料(以文字形式)
                console.log(data);
		}
	}
}

傳送多次Ajax請求

//基於Promise傳送Ajax請求
function queryData(url) {
   var p = new Promise(function(resolve,reject) {
         var xhr =  new XMLHttpRequest();
         //每當 readyState 改變時,就會觸發 onreadystatechange 事件
         xhr.onreadystatechange =function() {
             if(xhr.readyState != 4) return;
             if(xhr.readyState === 4 && xhr.status  ===200) {
                resolve(xhr.responseText);//拿到響應資料(以文字形式)
             } else {
                reject('伺服器錯誤');
              }
          };
          xhr.open('get',url);
          xhr.send(null);
          });
          return p;
    }
    //在這裡我們解決傳送多個Ajax請求,並把保證其順序,利用Promise的.then()方法
    //在這裡我們忽略請求錯誤的情況
    queryData('http://localhost:3000/data')
        .then(function(data){
           console.log(data)
           //在這裡return的時一個新的Promise物件
           return queryData('http://localhost:3000/data1')
         })
         //這裡呼叫的是上面return的Promise物件並且函數中的data用於接受上一個非同步任務的處理結果
    .then(function(data){
           console.log(data)
           return queryData('http://localhost:3000/data2')
         })
         .then(function(data){
           console.log(data)
         })

then
我們來對Promise範例物件的then方法做個分析

then的引數中的函數返回值有兩個
  • 返回Promise範例物件
    – 返回的該範例物件會呼叫下一個then
  • 返回普通值
    –返回的普通值會直接傳遞給下一個then,通過then引數中函數的引數接受該值
    –這裡注意,當引數是普通值時,會預設建立一個新的Promise範例物件,保證then 的鏈式程式設計可以正常進行下去

promise中常用的API

var p = new Promise(function(resolve,reject)

1.實體方法

  • p.then() 得到非同步任務的正確結果
  • p.catch() 獲取異常資訊
  • p.finally()成功與否都會執行(可以做一些提示資訊)

2.promise的物件方法

  • promise.all() 並行處理多個非同步任務,所有任務都執行完成才能得到結果
  • promise.race() 並行處理多個非同步任務,只要有一個任務完成就能得到結果

下面我們用程式碼來看看

//基於Promise傳送Ajax請求
function queryData(url) {
   var p = new Promise(function(resolve,reject) {
         var xhr =  new XMLHttpRequest();
         //每當 readyState 改變時,就會觸發 onreadystatechange 事件
         xhr.onreadystatechange =function() {
             if(xhr.readyState != 4) return;
             if(xhr.readyState === 4 && xhr.status  ===200) {
                resolve(xhr.responseText);//拿到響應資料(以文字形式)
             } else {
                reject('伺服器錯誤');
              }
          };
          xhr.open('get',url);
          xhr.send(null);
          });
          return p;
    }
var p1 = queryData('http://localhost:3000/a1');
var p2 = queryData('http://localhost:3000/a1');
var p3 = queryData('http://localhost:3000/a1');
//promise.all 在拿到三個返回資料後列印三個值
Promise.all([p1,p2,p3]).then(function(result){
     console.log(result)
})
//promise.race 在拿到第一個返回資料就只輸出它的值
Promise.race([p1,p2,p3]).then(function(result){
     console.log(result)
})