天天看點

JavaScript PromisePromise

文章目錄

  • Promise
    • 概述
    • Promise狀态
    • 基本用法
      • Promise
      • then
      • catch
      • finally
      • Promise.all()
      • Promise.race()
      • Promise.allSettled()
      • Promise.resolve()
      • Promise.reject()
    • 實際應用

Promise

概述

  • Promise是異步操作的一種解決方案
  • Promise一般用來解決層層嵌套的回調函數問題(回調地獄)

Promise狀态

  1. pending 進行中
  2. fulfilled 已成功
  3. rejected 已失敗

基本用法

Promise

  • Promise建立後會立即執行
  • Promise構造函數接收一個函數作為參照,該函數的兩個參數分為為

    resolve

    reject

    • resolve

      :将Promise對象的狀态從“進行中”變為“成功”
    • reject

      :将Promise對象的狀态從“進行中”變為“失敗”
const p = new Promise(function(resolve, reject) {
    console.log("hello Promise");
    resolve();
});
console.log(p); 

//hello Promise
//Promise {<pending>}
           

then

  • then()

    方法可以接收兩個回調函數:第一個回調函數是Promise對象的狀态變為

    resolved

    時調用,第二個回調函數是Promise對象的狀态變為

    rejected

    時調用。這兩個回調函數是可選的。
new Promise((resolve, reject) => {
    resolve("hello 成功");
    // reject("hello 失敗");
})
    .then(
    (succssMsg) => {
        console.log(`成功回調:${succssMsg}`);
    },
    (errMsg) => {
        console.log(`失敗回調:${errMsg}`);
    }
);

//成功回調:hello 成功
           

catch

  • catch()

    方法是專門 處理失敗狀态
new Promise((resolve, reject) => {
    reject("hello 失敗");
})
    .then(
    (succssMsg) => {
        console.log(`成功回調:${succssMsg}`);
    }
)
    .catch(
    (errMsg) => {
        console.log(`失敗回調:${errMsg}`);
    }
);

//失敗回調:hello 失敗
           

finally

  • finally()

    方法是最後一定會被執行
new Promise((resolve, reject) => {
    resolve("hello 成功");
    // reject("hello 失敗");
})
    .then(
    (succssMsg) => {
        console.log(`成功回調:${succssMsg}`);
    }
)
    .catch(
    (errMsg) => {
        console.log(`失敗回調:${errMsg}`);
    }
)
    .finally(
    () => {
        console.log("執行完畢");
    }
);

//成功回調:hello 成功
//執行完畢
           

Promise.all()

  • Promise.all()

    觀察所有Promise對象的狀态變化
  • 所有狀态為resolved時,最終狀态才會變為resolved
  • 隻要有一個為rejected,最終狀态為rejected
const p1 = new Promise((resolve, reject) => {
    resolve("yes1");
});

const p2 = new Promise((resolve, reject) => {
    resolve("yes2");
});

Promise.all([p1, p2])
    .then( result => console.log("成功:" + result) )
    .catch( err => console.log("失敗:" + err) );

//成功:yes1,yes2
           
const p1 = new Promise((resolve, reject) => {
    // resolve("yes1");
    // reject("no1");
    throw new Error("報錯了");
});

const p2 = new Promise((resolve, reject) => {
    resolve("yes2");
    // reject("no2");
});

Promise.all([p1, p2])
    .then( result => console.log("成功:" + result) )
    .catch( err => console.log("失敗:" + err) );

//失敗:Error: 報錯了
           

Promise.race()

  • Promise.race()

    最終狀态取決于率先完成的Promise執行個體對象,如果第一個完成對象的成功了,那最終就成功,如果第一個完成對象的失敗,那就最終失敗
const p1 = new Promise((resolve, reject) => {
    resolve("yes1");
    // reject("no1");
});

const p2 = new Promise((resolve, reject) => {
    // resolve("yes2");
    reject("no2");
});

Promise.race([p1, p2])
    .then(
    result => console.log("成功:" + result)
)
    .catch(
    err => console.log("失敗:" + err)
);

//成功:yes1
           

Promise.allSettled()

  • Promise.allSettled()

    會記錄所有Promise對象的狀态,隻有等這些對象都傳回結果才會結束
const p1 = new Promise((resolve, reject) => {
    resolve("yes1");
});

const p2 = new Promise((resolve, reject) => {
    reject("no2");
});

Promise.allSettled([p1, p2])
    .then(
    results => {
        console.log(results);
    }
);

//{status: "fulfilled", value: "yes1"}
//{status: "rejected", reason: "no2"}
           

Promise.resolve()

  • Promise.resolve()

    成功狀态簡寫
Promise.resolve("hello 成功")
//等價于
new Promise(resolve => resolve("成功"));
           

Promise.reject()

  • Promise.reject()

    失敗狀态簡寫
Promise.reject("hello 失敗");
//等價于
new Promise((resolve, reject) => reject("hello 失敗"));
           

實際應用

異步加載圖檔

<img id="myImg" src="" alt="">

<script>
    let myImg = document.querySelector("#myImg");

    const asyncLoadImage = (url) => {
        return new Promise((resolve, reject) => {
            var image = new Image();
            image.src = url;

            image.onload = () => {
                resolve(image.src);
            };

            image.onerror = () => {
                reject(new Error("加載失敗"));
            };
        });
    };

    asyncLoadImage("https://www.baidu.com/img/flexible/logo/pc/[email protected]")
        .then(
        (value) => {
            console.log(value);
            myImg.src = value;
        })
        .catch(
        (reason) => {
            console.log(reason);
        });
</script>
           

繼續閱讀