成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Promise 對(duì)象的理解

church / 1571人閱讀

摘要:使用對(duì)象的好處在于可以將異步操作以同步操作的流程表達(dá)出來(lái),避免了層層嵌套的回調(diào)函數(shù)。對(duì)象異步操作拋出錯(cuò)誤,狀態(tài)就會(huì)變?yōu)椋蜁?huì)調(diào)用方法指定的回調(diào)函數(shù)處理這個(gè)錯(cuò)誤。

Promise 含義

Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。它由社區(qū)最早提出和實(shí)現(xiàn),ES6 將其寫進(jìn)了語(yǔ)言標(biāo)準(zhǔn),統(tǒng)一了用法,原生提供了 Promise 對(duì)象。

所謂 Promise,簡(jiǎn)單說(shuō)就是一個(gè)容器,里面保存著某個(gè)未來(lái)才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果。從語(yǔ)法上說(shuō),Promise 是一個(gè)對(duì)象,從它可以獲取異步操作的消息。Promise 提供統(tǒng)一的 API,各種異步操作都可以用同樣的方法進(jìn)行處理。

Promise 對(duì)象有以下兩個(gè)特點(diǎn):

對(duì)象的狀態(tài)不受外界影響。有三種狀態(tài),分別為 pending(進(jìn)行中)、fulfilled(已成功)和 rejected(已失?。?。

一旦狀態(tài)改變,就不會(huì)再變,任何時(shí)候都可以得到這個(gè)結(jié)果。狀態(tài)改變只有兩種可能:從 pending 變?yōu)?fulfilled 和從 pending 變?yōu)?rejected。

使用 Promise 對(duì)象的好處在于:

可以將異步操作以同步操作的流程表達(dá)出來(lái),避免了層層嵌套的回調(diào)函數(shù)。

Promise 對(duì)象提供統(tǒng)一的接口,使得控制異步操作更加容易。

Promise 缺點(diǎn):

無(wú)法取消 Promise,一旦新建它就會(huì)立即執(zhí)行,無(wú)法中途取消。

如果不設(shè)置回調(diào)函數(shù),Promise 內(nèi)部拋出的錯(cuò)誤,不會(huì)反應(yīng)到外部。

當(dāng)處于 pending 狀態(tài)時(shí),無(wú)法得知目前進(jìn)展到哪一個(gè)階段(剛剛開始還是即將完成)。

基本用法

ES6 規(guī)定,Promise 對(duì)象是一個(gè)構(gòu)造函數(shù),用來(lái)生成 Promise 實(shí)例。

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 構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù),該函數(shù)的兩個(gè)參數(shù)分別是 resolve 和 reject。它們是兩個(gè)函數(shù),由 JavaScript 引擎提供,不用自己部署。

resolve 函數(shù)的作用:將 Promise 對(duì)象的狀態(tài)從“未完成(pending)”變?yōu)椤俺晒Γ╮esolved)”,在異步操作成功時(shí)調(diào)用,并將異步操作的結(jié)果作為參數(shù)傳遞出去。

reject 函數(shù)的作用:將 Promise 對(duì)象的狀態(tài)從“未完成(pending)”變?yōu)椤笆。╮ejected)”在異步操作失敗時(shí)調(diào)用,并將異步操作報(bào)出的錯(cuò)誤,作為參數(shù)傳遞出去。

then 方法作用:接受兩個(gè)回調(diào)函數(shù)作為參數(shù)。第一個(gè)回調(diào)函數(shù)是 Promise 對(duì)象的狀態(tài)變?yōu)?resolved 時(shí)調(diào)用,第二個(gè)回調(diào)函數(shù)是 Promise 對(duì)象的狀態(tài)變?yōu)?rejected 時(shí)調(diào)用。第二個(gè)函數(shù)可選,不一定要提供,也可以將第二個(gè)函數(shù)作為 catch 方法的參數(shù)。

catch 方法作用:用于指定發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)。Promise 對(duì)象異步操作拋出錯(cuò)誤,狀態(tài)就會(huì)變?yōu)?rejected,就會(huì)調(diào)用 catch 方法指定的回調(diào)函數(shù)處理這個(gè)錯(cuò)誤。另外,then 方法指定的回調(diào)函數(shù),如果運(yùn)行中拋出錯(cuò)誤,也會(huì)被 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時(shí)打印 "失敗:Error: test"
    console.log("失敗:" + err);
  });
Promise 執(zhí)行順序

Promise 新建后立即執(zhí)行,then 方法指定的回調(diào)函數(shù),將在當(dāng)前腳本所有同步任務(wù)執(zhí)行完才會(huì)執(zhí)行,catch 同理。

調(diào)用 resolve 或 reject 并不會(huì)終結(jié) Promise 的參數(shù)函數(shù)的執(zhí)行。

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

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

console.log("我是第二個(gè)執(zhí)行的");
resolve 函數(shù)和 reject 函數(shù)的參數(shù)

reject 函數(shù)的參數(shù)通常是 Error 對(duì)象的實(shí)例,表示拋出的錯(cuò)誤;resolve 函數(shù)的參數(shù)除了正常的值以外,還可能是另一個(gè) Promise 實(shí)例。

如果一個(gè) Promise(P2) 的 resolve 參數(shù)是另一個(gè) Promise(P1),此時(shí) P1 的狀態(tài)就會(huì)傳給 P2,P1 的狀態(tài)決定了 P2 的狀態(tài),P1 的狀態(tài)改變,P2 的回調(diào)函數(shù)才會(huì)執(zhí)行。

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 是一個(gè) Promise,3 秒之后變?yōu)?rejected。p2 的狀態(tài)在 1 秒之后改變,resolve 方法返回的是 p1。由于 p2 返回的是另一個(gè) Promise,導(dǎo)致 p2 自己的狀態(tài)無(wú)效了,由 p1 的狀態(tài)決定 p2 的狀態(tài)。所以,后面的 then 語(yǔ)句都變成針對(duì)后者(p1)。又過(guò)了 2 秒,p1 變?yōu)?rejected,導(dǎo)致觸發(fā) catch 方法指定的回調(diào)函數(shù)。

Promise 鏈?zhǔn)秸{(diào)用

then 方法可以返回一個(gè)新的 Promise 實(shí)例(注意,不是原來(lái)那個(gè) Promise 實(shí)例)。因此可以采用鏈?zhǔn)綄懛?,?then 方法后面再調(diào)用另一個(gè) 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
  });

注意:只要一個(gè) Promise 中拋出錯(cuò)誤,將執(zhí)行 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: 中止
  });

主動(dòng)終止 then 鏈,通過(guò) catch 方法來(lái)中止 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 對(duì)象最后狀態(tài)如何,都會(huì)執(zhí)行的操作。該方法是 ES2018 引入標(biāo)準(zhǔn)的。

finally 本質(zhì)上是 then 方法的特例,不接受任何參數(shù),不依賴于 Promise 的執(zhí)行結(jié)果

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

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

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

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

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

promise 的狀態(tài)由 promise1、promise2、promise3 決定,分成兩種情況。

只有 promise1、promise2、promise3 的狀態(tài)都變成 fulfilled,p 的狀態(tài)才會(huì)變成 fulfilled,此時(shí) promise1、promise2、promise3 的返回值組成一個(gè)數(shù)組,傳遞給 p 的回調(diào)函數(shù)。

只要 promise1、promise2、promise3 之中有一個(gè)被 rejected,promise 的狀態(tài)就變成 rejected,此時(shí)第一個(gè)被 reject 的實(shí)例的返回值,會(huì)傳遞給 promise 的回調(diào)函數(shù)。

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

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

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

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

如果 p2 沒(méi)有自己的 catch 方法,就會(huì)調(diào)用 Promise.all()的 catch 方法。

Promise.race()

Promise.race 方法同樣是將多個(gè) Promise 實(shí)例,包裝成一個(gè)新的 Promise 實(shí)例。

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

只要 p1、p2、p3 之中有一個(gè)實(shí)例率先改變狀態(tài),p 的狀態(tài)就跟著改變。那個(gè)率先改變的 Promise 實(shí)例的返回值,就傳遞給 p 的回調(diào)函數(shù)。

Promise.race 方法的參數(shù)與 Promise.all 方法一樣,如果不是 Promise 實(shí)例,就會(huì)先調(diào)用下面講到的 Promise.resolve 方法,將參數(shù)轉(zhuǎn)為 Promise 實(shí)例,再進(jìn)一步處理。

Promise.resolve()

將現(xiàn)有對(duì)象轉(zhuǎn)化為 Promise 對(duì)象。

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

參數(shù)是 Promise 實(shí)例,該方法不做任何改變。

參數(shù)是一個(gè) thenable 對(duì)象,先將對(duì)象轉(zhuǎn)為 Promise 對(duì)象,然后立即執(zhí)行 thenable 方法。相當(dāng)于將 thenable 對(duì)象中的 then 方法處理的值作為參數(shù)傳給 promise then 方法。

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

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

參數(shù)不是具有 then 方法的對(duì)象,或根本就不是對(duì)象,則 Promise.resolve 方法返回一個(gè)新的 Promise 對(duì)象,狀態(tài)為 resolved。

Promise.reject()

Promise.reject(reason)方法也會(huì)返回一個(gè)新的 Promise 實(shí)例,該實(shí)例的狀態(tài)為 rejected。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/103253.html

相關(guān)文章

  • Promise理解

    摘要:中就是一個(gè)構(gòu)造函數(shù)函數(shù)也是對(duì)象為什么需要多個(gè)嵌套的異步操作,如果直接用方式,會(huì)導(dǎo)致的出現(xiàn)使得異步操作更加規(guī)范,更加統(tǒng)一。的方法構(gòu)造函數(shù)構(gòu)造函數(shù)用于生成對(duì)象,函數(shù)在構(gòu)造函數(shù)執(zhí)行時(shí)同步執(zhí)行。 什么是Promise? 含以上:抽象異步操作的工具。javascript中:Promise就是一個(gè)構(gòu)造函數(shù)(函數(shù)也是對(duì)象) 為什么需要Promise? 1.多個(gè)嵌套的異步操作,如果直接用callbac...

    Binguner 評(píng)論0 收藏0
  • JavaScript 異步

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

    tuniutech 評(píng)論0 收藏0
  • promise async await 理解筆記

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

    NoraXie 評(píng)論0 收藏0
  • 理解 Javascript 中 Promise

    摘要:理解承諾有兩個(gè)部分。如果異步操作成功,則通過(guò)的創(chuàng)建者調(diào)用函數(shù)返回預(yù)期結(jié)果,同樣,如果出現(xiàn)意外錯(cuò)誤,則通過(guò)調(diào)用函數(shù)傳遞錯(cuò)誤具體信息。這將與理解對(duì)象密切相關(guān)。這個(gè)函數(shù)將創(chuàng)建一個(gè),該將在到秒之間的隨機(jī)數(shù)秒后執(zhí)行或。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! showImg(https://segmentfault.com/img/bVbkNvF?w=1280&h=...

    paulli3 評(píng)論0 收藏0
  • 理解 Javascript 中 Promise

    摘要:理解承諾有兩個(gè)部分。如果異步操作成功,則通過(guò)的創(chuàng)建者調(diào)用函數(shù)返回預(yù)期結(jié)果,同樣,如果出現(xiàn)意外錯(cuò)誤,則通過(guò)調(diào)用函數(shù)傳遞錯(cuò)誤具體信息。這將與理解對(duì)象密切相關(guān)。這個(gè)函數(shù)將創(chuàng)建一個(gè),該將在到秒之間的隨機(jī)數(shù)秒后執(zhí)行或。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! showImg(https://segmentfault.com/img/bVbkNvF?w=1280&h=...

    chaos_G 評(píng)論0 收藏0
  • [譯] 深入理解 Promise 五部曲:4. 擴(kuò)展問(wèn)題

    摘要:有一個(gè)和相關(guān)的更大的問(wèn)題。最后,請(qǐng)負(fù)有責(zé)任感并且使用安全的擴(kuò)展。深入理解五部曲異步問(wèn)題深入理解五部曲轉(zhuǎn)換問(wèn)題深入理解五部曲可靠性問(wèn)題深入理解五部曲擴(kuò)展性問(wèn)題深入理解五部曲樂(lè)高問(wèn)題最后,安利下我的個(gè)人博客,歡迎訪問(wèn) 原文地址:http://blog.getify.com/promis... 現(xiàn)在,我希望你已經(jīng)看過(guò)深入理解Promise的前三篇文章了。并且假設(shè)你已經(jīng)完全理解Promises...

    Shimmer 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<