ES6新特性六:promise對(duì)象實(shí)例詳解
本文實(shí)例講述了ES6新特性之promise對(duì)象。分享給大家供大家參考,具體如下:
1. promise 介紹
它是一個(gè)對(duì)象,也就是說(shuō)與其他JavaScript對(duì)象的用法,沒(méi)有什么兩樣;其次,它起到代理作用(proxy),充當(dāng)異步操作與回調(diào)函數(shù)之間的中介。它使得異步操作具備同步操作的接口,使得程序具備正常的同步運(yùn)行的流程,回調(diào)函數(shù)不必再一層層嵌套。
它的思想是,每一個(gè)異步任務(wù)立刻返回一個(gè)Promise對(duì)象,由于是立刻返回,所以可以采用同步操作的流程。這個(gè)Promises對(duì)象有一個(gè)then方法,允許指定回調(diào)函數(shù),在異步任務(wù)完成后調(diào)用。
異步操作f1返回一個(gè)Promise對(duì)象,它的回調(diào)函數(shù)f2寫法如下
(new Promise(f1)).then(f2);
2. promise 對(duì)象的三種狀態(tài)
① 異步操作未完成(pending)
② 異步操作已完成(resolved)
③ 異步操作失?。╮ejected)
3. 工作過(guò)程
Promise對(duì)象使用then方法添加回調(diào)函數(shù)。then方法可以接受兩個(gè)回調(diào)函數(shù),第一個(gè)是異步操作成功時(shí)(變?yōu)閞esolved狀態(tài))時(shí)的回調(diào)函數(shù),第二個(gè)是異步操作失?。ㄗ?yōu)閞ejected)時(shí)的回調(diào)函數(shù)(可以省略)。一旦狀態(tài)改變,就調(diào)用相應(yīng)的回調(diào)函數(shù),這兩個(gè)回調(diào)函數(shù)都接受異步操作傳回的值作為參數(shù)。
promise.then( console.log, console.error );
4. then 的鏈?zhǔn)绞褂?/strong>
① 首先then方法返回的一個(gè)新的promise對(duì)象,因此可以采用鏈?zhǔn)綄懛ā?/p>
② then方法的第一個(gè)參數(shù)是Resolved狀態(tài)的回調(diào)函數(shù),第二個(gè)參數(shù)(可選)是Rejected狀態(tài)的回調(diào)函數(shù)。
③ 如下,promise的狀態(tài)一旦變?yōu)閞esolved,就依次調(diào)用后面每一個(gè)then指定的回調(diào)函數(shù),每一步都必須等到前一步完成,才會(huì)執(zhí)行。最后一個(gè)then方法的回調(diào)函數(shù)console.log和console.error,用法上有一點(diǎn)重要的區(qū)別。console.log只顯示回調(diào)函數(shù)step3的返回值,console.error可以顯示step1、step2、step3之中任意一個(gè)發(fā)生的錯(cuò)誤,Promises對(duì)象的錯(cuò)誤有傳遞性。
promise .then(step1) .then(step2) .then(step3) .then( console.log, console.error );
5. promise 對(duì)象的使用
var promise = new Promise(function(resolve, reject) { // promise的構(gòu)造函數(shù),Promise構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù),該函數(shù)的兩個(gè)參數(shù)分別是resolve和reject // 異步操作的代碼 if (/* 異步操作成功 */){ resolve(value);//將異步的操作結(jié)果作為參數(shù)傳遞出去 } else { reject(error); } });
其中resolve和reject它們是兩個(gè)函數(shù),由JavaScript引擎提供,不用自己部署。
resolve函數(shù)的作用:將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤俺晒Α保磸腜ending變?yōu)镽esolved),在異步操作成功時(shí)調(diào)用,并將異步操作的結(jié)果,作為參數(shù)傳遞出去;
reject函數(shù)的作用:將Promise對(duì)象的狀態(tài)從“未完成”變?yōu)椤笆 保磸腜ending變?yōu)镽ejected),在異步操作失敗時(shí)調(diào)用,并將異步操作報(bào)出的錯(cuò)誤,作為參數(shù)傳遞出去。
① 下面是一個(gè)用Promise對(duì)象實(shí)現(xiàn)的Ajax操作的例子
var getJSON = function(url) { var promise = new Promise(function(resolve, reject){ var client = new XMLHttpRequest(); client.open("GET", url); client.onreadystatechange = handler; client.responseType = "json"; client.setRequestHeader("Accept", "application/json"); client.send(); function handler() { if (this.readyState !== 4) { return; } if (this.status === 200) { resolve(this.response);//會(huì)將參數(shù)傳遞給回調(diào)函數(shù) } else { reject(new Error(this.statusText)); } }; }); return promise; }; getJSON("/posts.json").then(function(json) { console.log('Contents: ' + json); }, function(error) { console.error('出錯(cuò)了', error); });
② resolve函數(shù)的參數(shù)除了正常的值以外,還可能是另一個(gè)Promise實(shí)例,即一個(gè)異步操作的結(jié)果是返回另一個(gè)異步操作。
var p1 = new Promise(function (resolve, reject) { // ... }); var p2 = new Promise(function (resolve, reject) { // ... resolve(p1); })
6.Promise.prototype.catch()
① 一個(gè) Promise 對(duì)象,如果異步操作拋出錯(cuò)誤,狀態(tài)就會(huì)變?yōu)镽ejected,就會(huì)調(diào)用catch方法指定的回調(diào)函數(shù),處理這個(gè)錯(cuò)誤。
promise.then(function(posts) { // ... }).catch(function(error) { // 處理 getJSON 和 前一個(gè)回調(diào)函數(shù)運(yùn)行時(shí)發(fā)生的錯(cuò)誤 console.log('發(fā)生錯(cuò)誤!', error); });
② 另外,then方法指定的回調(diào)函數(shù),如果運(yùn)行中拋出錯(cuò)誤,也會(huì)被catch方法捕獲。
var promise = new Promise(function(resolve, reject) { throw new Error('test'); }); promise.catch(function(error) { console.log(error); }); // Error: test
③ 另外兩種寫法
// 寫法一 var promise = new Promise(function(resolve, reject) { try { throw new Error('test'); } catch(e) { reject(e); } }); promise.catch(function(error) { console.log(error); }); // 寫法二 var promise = new Promise(function(resolve, reject) { reject(new Error('test'));//reject方法的作用,等同于拋出錯(cuò)誤 }); promise.catch(function(error) { console.log(error); });
④ Promise 在resolve語(yǔ)句后面再拋出錯(cuò)誤不會(huì)被捕獲。因?yàn)?Promise 的狀態(tài)一旦改變,就永久保持該狀態(tài),不會(huì)再變了。
var promise = new Promise(function(resolve, reject) { resolve('ok'); throw new Error('test'); }); promise .then(function(value) { console.log(value) }) .catch(function(error) { console.log(error) }); // ok
7 Promise.all()
參數(shù)為Promise 對(duì)象的數(shù)組;將多個(gè)Promisre 對(duì)象包裝成一個(gè)新的Promise 對(duì)象,如果數(shù)組中不是Promise 對(duì)象,就會(huì)自動(dòng)調(diào)用 Promise.resolve方法,將參數(shù)轉(zhuǎn)為Promise實(shí)例,再進(jìn)一步處理。(Promise.all方法的參數(shù)可以不是數(shù)組,但必須具有Iterator接口,且返回的每個(gè)成員都是Promise實(shí)例)
var p = Promise.all(promises).then(function (posts) { // ... }).catch(function(reason){ // ... });
① 只要promises之中有一個(gè)狀態(tài)變?yōu)閞ejected,p的狀態(tài)就變成rejected,此時(shí)第一個(gè)被reject的實(shí)例的返回值,會(huì)傳遞給p的回調(diào)函數(shù)。
② 如果全部都變?yōu)閞esolved;此時(shí) promises 數(shù)組中所有對(duì)象的返回值組成一個(gè)數(shù)組,傳遞給p的回調(diào)函數(shù)。
8 Promise.resolve()
將現(xiàn)有對(duì)象轉(zhuǎn)為 Promise對(duì)象,Promise.resolve方法就起到這個(gè)作用。
Promise.resolve('foo') // 等價(jià)于 new Promise(resolve => resolve('foo'))
① 參數(shù)為Priomise 對(duì)象,Promise.resolve() 不做任何處理。
② 參數(shù)是一個(gè)具有 then 方法的對(duì)象:Promise.resolve方法會(huì)將這個(gè)對(duì)象轉(zhuǎn)為Promise對(duì)象,然后就立即執(zhí)行thenable對(duì)象的then方法。
let thenable = { then: function(resolve, reject) { resolve(42); } }; let p1 = Promise.resolve(thenable);//p1為一個(gè)狀態(tài)已經(jīng)是resolved 的promise對(duì)象. p1.then(function(value) { console.log(value); // 42 });
③ 參數(shù)不是具有then方法的對(duì)象,或根本就不是對(duì)象
該參數(shù)變?yōu)樯傻?Promise 對(duì)象的 resolve() 的參數(shù)。
var p = Promise.resolve('Hello');//Hello 會(huì)傳遞給 p 的resolve() p.then(function (s){ console.log(s) }); // Hello
希望本文所述對(duì)大家ECMAScript程序設(shè)計(jì)有所幫助。
- ES6中非常實(shí)用的新特性介紹
- JavaScript ES6的新特性使用新方法定義Class
- JavaScript中的Reflect對(duì)象詳解(ES6新特性)
- 深入淺出ES6新特性之函數(shù)默認(rèn)參數(shù)和箭頭函數(shù)
- 簡(jiǎn)單談?wù)凟S6的六個(gè)小特性
- ES6新特性之Symbol類型用法分析
- ES6(ECMAScript 6)新特性之模板字符串用法分析
- ES6新特性之變量和字符串用法示例
- ES6新特性之模塊Module用法詳解
- ES6新特性之字符串的擴(kuò)展實(shí)例分析
- ES6新特性二:Iterator(遍歷器)和for-of循環(huán)詳解
- ES6新特性七:數(shù)組的擴(kuò)充詳解
- ES6新特性八:async函數(shù)用法實(shí)例詳解
- ES6新特性之類(Class)和繼承(Extends)相關(guān)概念與用法分析
- 讓微信小程序支持ES6中Promise特性的方法詳解
- ES6新特性:使用export和import實(shí)現(xiàn)模塊化詳解
- es6新特性之 class 基本用法解析
- ES6 13個(gè)新特性總結(jié)
相關(guān)文章
javascript 傳統(tǒng)事件模型構(gòu)造的事件監(jiān)聽(tīng)器實(shí)現(xiàn)代碼
最近做東西需要添加大量的事件,而且要對(duì)所有事件進(jìn)行比較細(xì)致的控制,于是便試著寫了個(gè)事件監(jiān)聽(tīng)器。2010-05-05JS實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)參數(shù)不丟失的方法
這篇文章主要介紹了JS實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)參數(shù)不丟失的方法,結(jié)合實(shí)例形式對(duì)比分析了javascript URL加密函數(shù)escape()、encodeURI()與encodeURIComponent()的功能與相關(guān)使用技巧,需要的朋友可以參考下2016-11-11canvas簡(jiǎn)單快速的實(shí)現(xiàn)知乎登錄頁(yè)背景效果
本篇文章主要介紹了canvas簡(jiǎn)單快速實(shí)現(xiàn)知乎登錄頁(yè)背景效果的相關(guān)知識(shí),具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-05-05canvas實(shí)現(xiàn)愛(ài)心和彩虹雨效果
本文主要介紹了canvas實(shí)現(xiàn)愛(ài)心和彩虹雨效果的實(shí)例,具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-03-03基于JavaScript實(shí)現(xiàn)簡(jiǎn)單的輪播圖
這篇文章主要為大家詳細(xì)介紹了基于JavaScript實(shí)現(xiàn)簡(jiǎn)單的輪播圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03