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

資訊專欄INFORMATION COLUMN

Promise 對象的理解

church / 1568人閱讀

摘要:使用對象的好處在于可以將異步操作以同步操作的流程表達出來,避免了層層嵌套的回調函數。對象異步操作拋出錯誤,狀態就會變為,就會調用方法指定的回調函數處理這個錯誤。

Promise 含義

Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。它由社區最早提出和實現,ES6 將其寫進了語言標準,統一了用法,原生提供了 Promise 對象。

所謂 Promise,簡單說就是一個容器,里面保存著某個未來才會結束的事件(通常是一個異步操作)的結果。從語法上說,Promise 是一個對象,從它可以獲取異步操作的消息。Promise 提供統一的 API,各種異步操作都可以用同樣的方法進行處理。

Promise 對象有以下兩個特點:

對象的狀態不受外界影響。有三種狀態,分別為 pending(進行中)、fulfilled(已成功)和 rejected(已失敗)。

一旦狀態改變,就不會再變,任何時候都可以得到這個結果。狀態改變只有兩種可能:從 pending 變為 fulfilled 和從 pending 變為 rejected。

使用 Promise 對象的好處在于:

可以將異步操作以同步操作的流程表達出來,避免了層層嵌套的回調函數。

Promise 對象提供統一的接口,使得控制異步操作更加容易。

Promise 缺點:

無法取消 Promise,一旦新建它就會立即執行,無法中途取消。

如果不設置回調函數,Promise 內部拋出的錯誤,不會反應到外部。

當處于 pending 狀態時,無法得知目前進展到哪一個階段(剛剛開始還是即將完成)。

基本用法

ES6 規定,Promise 對象是一個構造函數,用來生成 Promise 實例。

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const num = Math.random();

    if (num > 0.5) {
      resolve(num);
    } else {
      reject(num);
    }
  }, 500);
});

promise.then(
  res => {
    console.log("成功:" + res);
  },
  err => {
    console.log("失敗:" + err);
  }
);

Promise 構造函數接受一個函數作為參數,該函數的兩個參數分別是 resolve 和 reject。它們是兩個函數,由 JavaScript 引擎提供,不用自己部署。

resolve 函數的作用:將 Promise 對象的狀態從“未完成(pending)”變為“成功(resolved)”,在異步操作成功時調用,并將異步操作的結果作為參數傳遞出去。

reject 函數的作用:將 Promise 對象的狀態從“未完成(pending)”變為“失敗(rejected)”在異步操作失敗時調用,并將異步操作報出的錯誤,作為參數傳遞出去。

then 方法作用:接受兩個回調函數作為參數。第一個回調函數是 Promise 對象的狀態變為 resolved 時調用,第二個回調函數是 Promise 對象的狀態變為 rejected 時調用。第二個函數可選,不一定要提供,也可以將第二個函數作為 catch 方法的參數。

catch 方法作用:用于指定發生錯誤時的回調函數。Promise 對象異步操作拋出錯誤,狀態就會變為 rejected,就會調用 catch 方法指定的回調函數處理這個錯誤。另外,then 方法指定的回調函數,如果運行中拋出錯誤,也會被 catch 方法捕獲。

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const num = Math.random();

    if (num > 0.5) {
      resolve(num);
    } else {
      reject(num);
    }
  }, 500);
});

promise
  .then(res => {
    console.log("成功:" + res);
  })
  .catch(err => {
    console.log("失敗:" + err);
  });

promise
  .then(res => {
    console.log("成功:" + res);
    throw new Error("test");
  })
  .catch(err => {
    // num > 0.5時打印 "失敗:Error: test"
    console.log("失敗:" + err);
  });
Promise 執行順序

Promise 新建后立即執行,then 方法指定的回調函數,將在當前腳本所有同步任務執行完才會執行,catch 同理。

調用 resolve 或 reject 并不會終結 Promise 的參數函數的執行。

const promise = new Promise((resolve, reject) => {
  console.log("我是第一個執行的");
  resolve();
});

promise.then(res => {
  console.log("我是第三個執行的");
});

console.log("我是第二個執行的");
resolve 函數和 reject 函數的參數

reject 函數的參數通常是 Error 對象的實例,表示拋出的錯誤;resolve 函數的參數除了正常的值以外,還可能是另一個 Promise 實例。

如果一個 Promise(P2) 的 resolve 參數是另一個 Promise(P1),此時 P1 的狀態就會傳給 P2,P1 的狀態決定了 P2 的狀態,P1 的狀態改變,P2 的回調函數才會執行。

const p1 = new Promise(function(resolve, reject) {
  setTimeout(() => reject(new Error("fail")), 3000);
});

const p2 = new Promise(function(resolve, reject) {
  setTimeout(() => resolve(p1), 1000);
});

p2.then(result => console.log(result)).catch(error => console.log(error));
// Error: fail

上面代碼中,p1 是一個 Promise,3 秒之后變為 rejected。p2 的狀態在 1 秒之后改變,resolve 方法返回的是 p1。由于 p2 返回的是另一個 Promise,導致 p2 自己的狀態無效了,由 p1 的狀態決定 p2 的狀態。所以,后面的 then 語句都變成針對后者(p1)。又過了 2 秒,p1 變為 rejected,導致觸發 catch 方法指定的回調函數。

Promise 鏈式調用

then 方法可以返回一個新的 Promise 實例(注意,不是原來那個 Promise 實例)。因此可以采用鏈式寫法,即 then 方法后面再調用另一個 then 方法。

const promise = new Promise((resolve, reject) => {
  resolve("promise");
})
  .then(res => {
    console.log(res); // promise
    return "promise1";
  })
  .then(res => {
    console.log(res); // promise1
    return "promise2";
  })
  .then(res => {
    console.log(res); // promise2
  });

注意:只要一個 Promise 中拋出錯誤,將執行 catch 方法,then 鏈終止。

const promise = new Promise((resolve, reject) => {
  resolve("promise");
})
  .then(res => {
    console.log(res); // promise
    throw new Error("中止");
    return "promise1";
  })
  .then(res => {
    console.log(res);
    return "promise2";
  })
  .then(res => {
    console.log(res);
  })
  .catch(err => {
    console.log(err); // Error: 中止
  });

主動終止 then 鏈,通過 catch 方法來中止 promise chain

const promise = new Promise((resolve, reject) => {
  resolve("promise");
})
  .then(res => {
    console.log(res); // promise
    return Promise.reject({
      notRealPromiseException: true
    });
  })
  .then(res => {
    console.log(res);
    return "promise2";
  })
  .then(res => {
    console.log(res);
  })
  .catch(err => {
    if (err.notRealPromiseException) {
      return true;
    }
    console.log(err);
  });
Promise.prototype.finally()

finally 方法用于指定不管 Promise 對象最后狀態如何,都會執行的操作。該方法是 ES2018 引入標準的。

finally 本質上是 then 方法的特例,不接受任何參數,不依賴于 Promise 的執行結果

promise.finally(() => {
  // 語句
});

// 等同于
promise.then(
  result => {
    // 語句
    return result;
  },
  error => {
    // 語句
    throw error;
  }
);
Promise.all()

Promise.all 方法用于將多個 Promise 實例,包裝成一個新的 Promise 實例。

const promise = Promise.all([promise1, promise2, promise3])

Promise.all 方法接受一個數組作為參數,promise、pro 米色、promise3 都是 Promise 實例,如果不是,就會先調用下面講到的 Promise.resolve 方法,將參數轉為 Promise 實例,再進一步處理。(Promise.all 方法的參數可以不是數組,但必須具有 Iterator 接口,且返回的每個成員都是 Promise 實例。了解 Iterator 接口)

promise 的狀態由 promise1、promise2、promise3 決定,分成兩種情況。

只有 promise1、promise2、promise3 的狀態都變成 fulfilled,p 的狀態才會變成 fulfilled,此時 promise1、promise2、promise3 的返回值組成一個數組,傳遞給 p 的回調函數。

只要 promise1、promise2、promise3 之中有一個被 rejected,promise 的狀態就變成 rejected,此時第一個被 reject 的實例的返回值,會傳遞給 promise 的回調函數。

const p1 = new Promise((resolve, reject) => {
  resolve("hello");
})
  .then(result => result)
  .catch(e => e);

const p2 = new Promise((resolve, reject) => {
  throw new Error("報錯了");
})
  .then(result => result)
  .catch(e => e);

Promise.all([p1, p2])
  .then(result => console.log(result))
  .catch(e => console.log(e));
// ["hello", Error: 報錯了]

上面代碼中,p1 會 resolved,p2 首先會 rejected,但是 p2 有自己的 catch 方法,該方法返回的是一個新的 Promise 實例,p2 指向的實際上是這個實例。該實例執行完 catch 方法后,也會變成 resolved,導致 Promise.all()方法參數里面的兩個實例都會 resolved,因此會調用 then 方法指定的回調函數,而不會調用 catch 方法指定的回調函數。

如果 p2 沒有自己的 catch 方法,就會調用 Promise.all()的 catch 方法。

Promise.race()

Promise.race 方法同樣是將多個 Promise 實例,包裝成一個新的 Promise 實例。

const p = Promise.race([p1, p2, p3])

只要 p1、p2、p3 之中有一個實例率先改變狀態,p 的狀態就跟著改變。那個率先改變的 Promise 實例的返回值,就傳遞給 p 的回調函數。

Promise.race 方法的參數與 Promise.all 方法一樣,如果不是 Promise 實例,就會先調用下面講到的 Promise.resolve 方法,將參數轉為 Promise 實例,再進一步處理。

Promise.resolve()

將現有對象轉化為 Promise 對象。

const promise = Promise.resolve("Hello world")

參數是 Promise 實例,該方法不做任何改變。

參數是一個 thenable 對象,先將對象轉為 Promise 對象,然后立即執行 thenable 方法。相當于將 thenable 對象中的 then 方法處理的值作為參數傳給 promise then 方法。

let thenObj = {
  then(resolve, reject) {
    resolve("Hello");
  }
};

const promise = Promise.resolve(thenObj);
promise.then(res => {
  console.log(res); // Hello
});

參數不是具有 then 方法的對象,或根本就不是對象,則 Promise.resolve 方法返回一個新的 Promise 對象,狀態為 resolved。

Promise.reject()

Promise.reject(reason)方法也會返回一個新的 Promise 實例,該實例的狀態為 rejected。

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

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

相關文章

  • Promise理解

    摘要:中就是一個構造函數函數也是對象為什么需要多個嵌套的異步操作,如果直接用方式,會導致的出現使得異步操作更加規范,更加統一。的方法構造函數構造函數用于生成對象,函數在構造函數執行時同步執行。 什么是Promise? 含以上:抽象異步操作的工具。javascript中:Promise就是一個構造函數(函數也是對象) 為什么需要Promise? 1.多個嵌套的異步操作,如果直接用callbac...

    Binguner 評論0 收藏0
  • JavaScript 異步

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。寫一個符合規范并可配合使用的寫一個符合規范并可配合使用的理解的工作原理采用回調函數來處理異步編程。 JavaScript怎么使用循環代替(異步)遞歸 問題描述 在開發過程中,遇到一個需求:在系統初始化時通過http獲取一個第三方服務器端的列表,第三方服務器提供了一個接口,可通過...

    tuniutech 評論0 收藏0
  • promise async await 理解筆記

    摘要:在異步編程中,提供了對象的方式。例如等同于所以可以理解為生成一個實例。那么自然也可以去調用則是配合使用的。等于是等待一個返回值,等待的執行結果。但是函數不會造成阻塞,所以配合使用,則沒有影響到外部。 在異步編程中,es6提供了promise對象的方式。簡單的用法 var promise = new Promise((resolve,reject)=>{ if(){ ...

    NoraXie 評論0 收藏0
  • 理解 Javascript 中 Promise

    摘要:理解承諾有兩個部分。如果異步操作成功,則通過的創建者調用函數返回預期結果,同樣,如果出現意外錯誤,則通過調用函數傳遞錯誤具體信息。這將與理解對象密切相關。這個函數將創建一個,該將在到秒之間的隨機數秒后執行或。 想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你! showImg(https://segmentfault.com/img/bVbkNvF?w=1280&h=...

    paulli3 評論0 收藏0
  • 理解 Javascript 中 Promise

    摘要:理解承諾有兩個部分。如果異步操作成功,則通過的創建者調用函數返回預期結果,同樣,如果出現意外錯誤,則通過調用函數傳遞錯誤具體信息。這將與理解對象密切相關。這個函數將創建一個,該將在到秒之間的隨機數秒后執行或。 想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你! showImg(https://segmentfault.com/img/bVbkNvF?w=1280&h=...

    chaos_G 評論0 收藏0
  • [譯] 深入理解 Promise 五部曲:4. 擴展問題

    摘要:有一個和相關的更大的問題。最后,請負有責任感并且使用安全的擴展。深入理解五部曲異步問題深入理解五部曲轉換問題深入理解五部曲可靠性問題深入理解五部曲擴展性問題深入理解五部曲樂高問題最后,安利下我的個人博客,歡迎訪問 原文地址:http://blog.getify.com/promis... 現在,我希望你已經看過深入理解Promise的前三篇文章了。并且假設你已經完全理解Promises...

    Shimmer 評論0 收藏0

發表評論

0條評論

church

|高級講師

TA的文章

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