javascript Promise簡(jiǎn)單學(xué)習(xí)使用方法小結(jié)
解決回調(diào)函數(shù)嵌套太深,并行邏輯必須串行執(zhí)行,一個(gè)Promise代表一個(gè)異步操作的最終結(jié)果,跟Promise交互的主要方式是通過他的then()方法來注冊(cè)回調(diào)函數(shù),去接收Promise的最終結(jié)果值
Promise相關(guān)的協(xié)議有PromiseA和PromiseA+
定義一個(gè)類Promise
定義屬性隊(duì)列queue,初始化空數(shù)組[]
定義屬性值value,初始化null
定義屬性狀態(tài)status,初始化“pending”(默認(rèn)值)
定義成員方法getQueue(),返回屬性queue
定義成員方法getStatus(),返回屬性status
定義成員方法setStatus(),設(shè)置狀態(tài),傳遞參數(shù):status,value
判斷status為fulfilled或者rejected,
設(shè)置status屬性this.status=status
設(shè)置value屬性this.value=value || null ,如果不傳value就是null
定義凍結(jié)變量freezeObject
定義成員方法isFulfilled(),判斷當(dāng)前狀態(tài)是否是(完成)
定義成員方法isRejected(),判斷當(dāng)前狀態(tài)是否是(失敗)
定義成員方法isPending(),判斷當(dāng)前狀態(tài)師傅是(等待)
定義成員方法then(),傳遞參數(shù):onFulfilled成功的回調(diào),onRejected失敗的回調(diào)
定義對(duì)象handler對(duì)象,屬性fulfilled,rejected兩個(gè)回調(diào)函數(shù)
定義handler對(duì)象的deferred屬性,Deferred對(duì)象
判斷當(dāng)前狀態(tài)是否等待,如果是等待 把handler對(duì)象塞入queue隊(duì)列數(shù)組
如果不是等待狀態(tài),調(diào)用Utils對(duì)象的procedure()方法,參數(shù):status,
返回 handler.deferred.promise對(duì)象
定義一個(gè)類Deferred
定義屬性promise,初始化Promise對(duì)象
定義成員方法resolve(),傳遞參數(shù):result結(jié)果
判斷Promise對(duì)象的狀態(tài)是 等待,直接返回
調(diào)用Promise對(duì)象的getQueue()方法,獲取queue數(shù)組
循環(huán)數(shù)組
//todo調(diào)用工具類Utils. procedure()方法,參數(shù):“fulfilled”,元素,err信息
調(diào)用Promise對(duì)象的setStatus()方法,設(shè)置狀態(tài),參數(shù):'fulfilled',result
定義成員方法reject,傳遞參數(shù):err錯(cuò)誤信息
判斷Promise對(duì)象的狀態(tài)是 等待,直接返回
調(diào)用Promise對(duì)象的getQueue()方法,獲取queue數(shù)組
循環(huán)數(shù)組
//todo,調(diào)用工具類Utils. procedure()方法,參數(shù):“rejected”,元素,err信息
調(diào)用Promise對(duì)象的setStatus()方法,設(shè)置狀態(tài),參數(shù):'fulfilled',result
定義工具類Utils,使用匿名函數(shù)立即執(zhí)行,得到一個(gè)對(duì)象
返回對(duì)象,對(duì)象中有一個(gè)方法procedure()
定義procedure()方法,傳遞參數(shù):type狀態(tài)類型,handler處理器數(shù)組,result結(jié)果
獲取到處理函數(shù)func,在handler[type]
到這里我看暈了。。。
使用方法:
定義一個(gè)函數(shù)ajax,傳遞參數(shù):url路徑
獲取Deferred對(duì)象,new出來
ajax請(qǐng)求數(shù)據(jù)的代碼,在返回?cái)?shù)據(jù)的回調(diào)方法中
如果成功了調(diào)用Deferred對(duì)象的resolve()方法,參數(shù):返回的數(shù)據(jù)
如果失敗了調(diào)用Deferred對(duì)象的reject()方法,參數(shù):返回的數(shù)據(jù)
返回Deferred.promise對(duì)象
調(diào)用ajax()方法,得到promise對(duì)象,參數(shù):url,
調(diào)用promise對(duì)象的then()方法,參數(shù):匿名函數(shù)
調(diào)用ajax()方法,獲取到promise對(duì)象,返回這個(gè)對(duì)象
形成鏈?zhǔn)秸{(diào)用
js部分:
<script> //Promise代碼部分(我選擇狗帶) Promise = function() { this.queue = []; this.value = null; this.status = 'pending';// pending fulfilled rejected }; Promise.prototype.getQueue = function() { return this.queue; }; Promise.prototype.getStatus = function() { return this.status; }; Promise.prototype.setStatus = function(s, value) { if (s === 'fulfilled' || s === 'rejected') { this.status = s; this.value = value || null; this.queue = []; var freezeObject = Object.freeze || function(){}; freezeObject(this);// promise的狀態(tài)是不可逆的 } else { throw new Error({ message: "doesn't support status: " + s }); } }; Promise.prototype.isFulfilled = function() { return this.status === 'fulfilled'; }; Promise.prototype.isRejected = function() { return this.status === 'rejected'; } Promise.prototype.isPending = function() { return this.status === 'pending'; } Promise.prototype.then = function(onFulfilled, onRejected) { var handler = { 'fulfilled': onFulfilled, 'rejected': onRejected }; handler.deferred = new Deferred(); if (!this.isPending()) {//這里允許先改變promise狀態(tài)后添加回調(diào) utils.procedure(this.status, handler, this.value); } else { this.queue.push(handler);//then may be called multiple times on the same promise;規(guī)范2.2.6 } return handler.deferred.promise;//then must return a promise;規(guī)范2.2.7 }; var utils = (function(){ var makeSignaler = function(deferred, type) { return function(result) { transition(deferred, type, result); } }; var procedure = function(type, handler, result) { var func = handler[type]; var def = handler.deferred; if (func) { try { var newResult = func(result); if (newResult && typeof newResult.then === 'function') {//thenable // 此種寫法存在閉包容易造成內(nèi)存泄露,我們通過高階函數(shù)解決 // newResult.then(function(data) { // def.resolve(data); // }, function(err) { // def.reject(err); // }); //PromiseA+規(guī)范,x代表newResult,promise代表def.promise //If x is a promise, adopt its state [3.4]: //If x is pending, promise must remain pending until x is fulfilled or rejected. //If/when x is fulfilled, fulfill promise with the same value. //If/when x is rejected, reject promise with the same reason. newResult.then(makeSignaler(def, 'fulfilled'), makeSignaler(def, 'rejected'));//此處的本質(zhì)是利用了異步閉包 } else { transition(def, type, newResult); } } catch(err) { transition(def, 'rejected', err); } } else { transition(def, type, result); } }; var transition = function(deferred, type, result) { if (type === 'fulfilled') { deferred.resolve(result); } else if (type === 'rejected') { deferred.reject(result); } else if (type !== 'pending') { throw new Error({ 'message': "doesn't support type: " + type }); } }; return { 'procedure': procedure } })(); Deferred = function() { this.promise = new Promise(); }; Deferred.prototype.resolve = function(result) { if (!this.promise.isPending()) { return; } var queue = this.promise.getQueue(); for (var i = 0, len = queue.length; i < len; i++) { utils.procedure('fulfilled', queue[i], result); } this.promise.setStatus('fulfilled', result); }; Deferred.prototype.reject = function(err) { if (!this.promise.isPending()) { return; } var queue = this.promise.getQueue(); for (var i = 0, len = queue.length; i < len; i++) { utils.procedure('rejected', queue[i], err); } this.promise.setStatus('rejected', err); } /*****************************上面看不懂,分割線************************************/ //測(cè)試部分 ajax = function(url) { var def = new Deferred(); var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if ((xhr.status >=200 && xhr.status < 300) || xhr.status === 304) { def.resolve(xhr.responseText) } else {//簡(jiǎn)化ajax,沒有提供錯(cuò)誤回調(diào) def.reject(new Error({ message: xhr.status })); } } }; xhr.open('get', url, true); xhr.send(null); return def.promise; } ajax('test.php?act=1').then(function(data1) { console.log(data1);//處理data1 return ajax('test.php?act=2'); }).then(function(data2) { console.log(data2);//處理data2 return ajax('test.php?act=3'); }, function(err) { console.error(err); }).then(function(data3) { console.log(data3); alert('success'); }, function(err) { console.error(err); }); </script>
php:
<?php if($_GET['act']==1){ echo json_encode(array("code"=>200)); }else if($_GET['act']==2){ echo json_encode(array("code"=>300)); }else if($_GET['act']==3){ echo json_encode(array("code"=>400)); }
以上這篇javascript Promise簡(jiǎn)單學(xué)習(xí)使用方法小結(jié)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript實(shí)現(xiàn)的聯(lián)動(dòng)菜單特效示例
這篇文章主要介紹了JavaScript實(shí)現(xiàn)的聯(lián)動(dòng)菜單特效,涉及javascript事件響應(yīng)及頁(yè)面元素屬性動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-07-07JS實(shí)現(xiàn)十分鐘倒計(jì)時(shí)代碼實(shí)例
在本篇文章里我們給大家分享了關(guān)于JS實(shí)現(xiàn)十分鐘倒計(jì)時(shí)的相關(guān)實(shí)例代碼,有需要的朋友們可以學(xué)習(xí)下。2018-10-10JavaScript實(shí)現(xiàn)水印效果的示例代碼
這篇文章主要為大家詳細(xì)介紹了JavaScript如何利用canvas實(shí)現(xiàn)添加水印的效果,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-05-05原生JS運(yùn)動(dòng)實(shí)現(xiàn)輪播圖
這篇文章主要為大家詳細(xì)介紹了原生JS運(yùn)動(dòng)實(shí)現(xiàn)輪播圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-01-01