Promise

Promise

異步編程的一種解決方案。是一個對象,從它可以獲取異步操作的信息。三種狀態(tài):pending,fulfilled,rejected。
缺點:一單建立就會立即執(zhí)行,無法中途取消;不設(shè)置回調(diào)函數(shù),Promise內(nèi)部破除的錯誤不會反應(yīng)到外部。

1:常見用法

//構(gòu)造函數(shù)
const promise = new Promise(function(resolve, reject) {
  // ... some code
  if (/* 異步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});
//使用返回的狀態(tài)
promise.then(function(value) {
  // success
}, function(error) {
  // failure
});
//執(zhí)行順序
let promise = new Promise(function(resolve, reject) {
  console.log('Promise');
  resolve();
});

promise.then(function() {
  console.log('resolved');
});

console.log('Hi!');
執(zhí)行結(jié)果
Promise;
Hi!
resolved
注:Promise 新建后就會立即執(zhí)行。所以先執(zhí)行 console.log('Promise');

new Promise((resolve, reject) => {
  resolve(1);
  console.log(2);
}).then(r => {
  console.log(r);
});
// 2
// 1
注:般來說,調(diào)用resolve或reject以后,Promise 的使命就完成了,后繼操作應(yīng)該放到then方法里面,而不應(yīng)該直接寫在resolve或reject的后面。所以,最好在它們前面加上return語句,這樣就不會有意外。
new Promise((resolve, reject) => {
  return resolve(1);
  // 后面的語句不會執(zhí)行
  console.log(2);
})
//1

Promise.prototype.then()

Promise 實例具有then方法,也就是說,then方法是定義在原型對象Promise.prototype上的。then方法的第一個參數(shù)是resolved狀態(tài)的回調(diào)函數(shù),第二個參數(shù)是rejected狀態(tài)的回調(diào)函數(shù),它們都是可選的。then方法返回的是一個新的Promise實例(注意,不是原來那個Promise實例)。因此可以采用鏈?zhǔn)綄懛ǎ磘hen方法后面再調(diào)用另一個then方法。

const getJSON = (url)=> {
  const promise = new Promise(function(resolve, reject){
    const client = new XMLHttpRequest();
    client.open("GET", url);
    const handler = function() {
      if (this.readyState !== 4) {
        return;
      }
      if (this.status === 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.statusText));
      }
    };
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();
  });

  return promise;
};
getJSON("/posts.json").then(function(json) {
  console.log('Contents: ' + json);
}, function(error) {
  console.error('出錯了', error);
});

getJSON('/posts.json').then(function(posts) {
  // ...
}).catch(function(error) {
  // 處理 getJSON 和 前一個回調(diào)函數(shù)運行時發(fā)生的錯誤
  console.log('發(fā)生錯誤!', error);
});
//下面兩個方法都能正確剖出錯誤
p.then((val) => console.log('fulfilled:', val))
  .catch((err) => console.log('rejected', err));

p.then((val) => console.log('fulfilled:', val))
  .then(null, (err) => console.log("rejected:", err));
//建議寫法
promise.then(function(data) { 
    // success
  }).catch(function(err) {
    // error
  });

Promise 內(nèi)部的錯誤不會影響到 Promise 外部的代碼,通俗的說法就是“Promise 會吃掉錯誤”。

const someAsyncThing = function() {
  return new Promise(function(resolve, reject) {
    // 下面一行會報錯,因為x沒有聲明
    resolve(x + 2);
  });
};

someAsyncThing().then(function() {
  console.log('everything is great');
});

setTimeout(() => { console.log(123) }, 2000);
// Uncaught (in promise) ReferenceError: x is not defined
// 123

Promise.prototype.finally()

finally()方法用于指定不管 Promise 對象最后狀態(tài)如何,都會執(zhí)行的操作。該方法是 ES2018 引入標(biāo)準(zhǔn)的。
finally方法的回調(diào)函數(shù)不接受任何參數(shù),這意味著沒有辦法知道,前面的 Promise 狀態(tài)到底是fulfilled還是rejected。這表明,finally方法里面的操作,應(yīng)該是與狀態(tài)無關(guān)的,不依賴于 Promise 的執(zhí)行結(jié)果。

promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});

//例子
server.listen(port)
  .then(function () {
    // ...
  })
  .finally(server.stop);

Promise.all()

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

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

Promise.allSettled()

有時候,我們希望等到一組異步操作都結(jié)束了,不管每一個操作是成功還是失敗,再進行下一步操作。但是,現(xiàn)有的 Promise 方法很難實現(xiàn)這個要求。
為了解決這個問題,ES2020 引入了Promise.allSettled()方法,用來確定一組異步操作是否都結(jié)束了(不管成功或失?。K?,它的名字叫做”Settled“,包含了”fulfilled“和”rejected“兩種情況。

Promise.any()

ES2021 引入了Promise.any()方法。該方法接受一組 Promise 實例作為參數(shù),包裝成一個新的 Promise 實例返回。
只要參數(shù)實例有一個變成fulfilled狀態(tài),包裝實例就會變成fulfilled狀態(tài);如果所有參數(shù)實例都變成rejected狀態(tài),包裝實例就會變成rejected狀態(tài)。

Promise.any()跟Promise.race()方法很像,只有一點不同,就是Promise.any()不會因為某個 Promise 變成rejected狀態(tài)而結(jié)束,必須等到所有參數(shù) Promise 變成rejected狀態(tài)才會結(jié)束。

Promise.any([
  fetch('https://v8.dev/').then(() => 'home'),
  fetch('https://v8.dev/blog').then(() => 'blog'),
  fetch('https://v8.dev/docs').then(() => 'docs')
]).then((first) => {  // 只要有一個 fetch() 請求成功
  console.log(first);
}).catch((error) => { // 所有三個 fetch() 全部請求失敗
  console.log(error);
});

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 搬運學(xué)習(xí),非原創(chuàng) Promise 的含義 Promise對象有以下兩個特點。 (1)對象的狀態(tài)不受外界影響。Pro...
    wsgdiv閱讀 267評論 0 0
  • Promise 的含義 Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更...
    硅谷干貨閱讀 304評論 0 0
  • Promise 的含義 Promise對象有以下兩個特點 :(1)對象的狀態(tài)不受外界影響。Promise對象代表一...
    前端末晨曦吖閱讀 594評論 0 0
  • 1.Promise 的含義 Promise 是異步編程的一種解決方案 Promise對象有以下兩個特點。 (1)對...
    黑云閱讀 531評論 0 5
  • 前言: 2020年是多災(zāi)多難的一年,疫情持續(xù)至今,到目前,全世界的經(jīng)濟都受到不同程序的影響,各大公司裁員,在這樣一...
    西巴擼閱讀 736評論 0 10

友情鏈接更多精彩內(nèi)容