日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

dojo/request模块整体架构解析

發布時間:2024/4/14 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 dojo/request模块整体架构解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  總體說明

  做前端當然少不了ajax的使用,使用dojo的童鞋都知道dojo是基于模塊化管理的前端框架,其中對ajax的處理位于dojo/request模塊。一般情況下我們使用ajax請求只需要引入dojo/request模塊,然后按照文檔的說明制定參數即可。實際上dojo在這一模塊的處理中抽象了很多概念:

  • 平臺偵探器:dojo/request/default
  • 請求分發器:dojo/request/registry
  • 全局通知器:dojo/request/notify
  • 數據傳輸器:dojo/request/xhr dojo/request/script dojo/request/iframe dojo/request/node
  • 數據轉化器:dojo/request/handlers

  處理器的總體關系如下圖所示:

  

  正是這些概念使得dojo在ajax請求上能夠提供強大的擴展性和簡捷的接口。

?

  Provider

  請求傳輸器被稱為Provider,dojo框架自身提供了以下4個provider

  • dojo/request/xhr 提供跨瀏覽器的XMLHttpRequest,在瀏覽器端它被作為默認的provider
  • dojo/request/node 用于node平臺的異步請求,在node下唄當做默認的provider。dojo是可以運行在node平臺下的,當然需要做一些配置,這是另一篇文章的主要內容
  • dojo/request/iframe 不刷新瀏覽器傳輸form表單,在文件上傳時經常用到
  • dojo/request/script 常以jsonp方式來進行跨域請求

  所有dojo自帶的Provider返回一個promise對象,其中有一個不在標準規范內的屬性:response。該屬性是一個標準promise對象,該對象將一個代表服務器端響應結果的對象作為fulfill狀態的值。這個對象有以下幾個屬性:

  關于這幾個Provider的詳細講解請繼續關注下一篇文章

  

  default

  一般情況下我們發送ajax請求時只需引入dojo/request即可,實際上這是在default中根據不同的運行平臺自動給我們提供了一個默認的provider。

1 define([ 2 'exports', 3 'require', 4 '../has' 5 ], function(exports, require, has){ 6 //讀取dojoConfig中的配置信息 7 var defId = has('config-requestProvider'), 8 platformId; 9 10 //根據不同平臺選擇不同的provider 11 if(has('host-browser') || has('host-webworker')){ 12 platformId = './xhr'; 13 }else if(has('host-node')){ 14 platformId = './node'; 15 /* TODO: 16 }else if(has('host-rhino')){ 17 platformId = './rhino'; 18 */ 19 } 20 21 if(!defId){ 22 defId = platformId; 23 } 24 25 exports.getPlatformDefaultId = function(){ 26 return platformId; 27 }; 28 //作為插件使用,是跟參數選擇provider 29 exports.load = function(id, parentRequire, loaded, config){ 30 require([id == 'platform' ? platformId : defId], function(provider){ 31 loaded(provider); 32 }); 33 }; 34 }); View Code

  代碼中關于exports跟require模塊的說明請看我的上一篇博客:require、module、exports dojo中的三個特殊模塊標識。

  上述內容關于load的函數的出現,意味著該模塊可以作為“插件”使用。dojo插件主要用于加載一些非AMD的資源,比如css、html。dojo中常用的插件有5個:

  • dojo/domReady?
  • dojo/text 用于加載靜態資源文件
  • dojo/i18n 加載國際化語言文件
  • dojo/has 用于特性檢測
  • dojo/require

  當在define或require中一個模塊引用包含一個!,dojo的加載器會自動將這個模塊引用字符串在!處分開,左邊部分作為一個模塊引用對待,右邊部分,等待左邊模塊加載完畢后交由模塊的load方法處理;

exports.load = function(id, parentRequire, loaded, config){require([id == 'platform' ? platformId : defId], function(provider){loaded(provider);});};

  關于load函數的幾個參數:

  • id:代表!右側部分
  • parentRequire:上下文智能的require請求器
  • loaded:id模塊加載完畢后的回調
  • config:猜測是dojo/_base/config

  后三個參數是dojo自己來處理,一般情況下我們不需要關心。

  關于插件還要在說幾句:   dojo中不會像緩存module一樣緩存插件所加載的資源比如:我們可以多次引用同一個module,但是這個module只會加載一次,這是AMD規范所強制規定的。但是我如果多次dojo/text!./template.html這個template.html會被加載多次。

  

  notify

  notify是全局的ajax事件通知器,負責全局范圍內的ajax事件監聽,有類似于jquery中ajaxStart、ajaxComplete的事件。

1 define(['../Evented', '../_base/lang', './util'], function(Evented, lang, util){ 2 // module: 3 // dojo/request/notify 4 // summary: 5 // Global notification API for dojo/request. Notifications will 6 // only be emitted if this module is required. 7 // 8 // | require('dojo/request', 'dojo/request/notify', 9 // | function(request, notify){ 10 // | notify('load', function(response){ 11 // | if(response.url === 'someUrl.html'){ 12 // | console.log('Loaded!'); 13 // | } 14 // | }); 15 // | request.get('someUrl.html'); 16 // | } 17 // | ); 18 19 var pubCount = 0, 20 slice = [].slice; 21 //實例化dojo/Evented對象,負責分發事件 22 var hub = lang.mixin(new Evented, { 23 onsend: function(data){ 24 if(!pubCount){ 25 this.emit('start'); 26 } 27 pubCount++; 28 }, 29 _onload: function(data){ 30 this.emit('done', data); 31 }, 32 _onerror: function(data){ 33 this.emit('done', data); 34 }, 35 _ondone: function(data){ 36 if(--pubCount <= 0){ 37 pubCount = 0; 38 this.emit('stop'); 39 } 40 }, 41 emit: function(type, event){ 42 var result = Evented.prototype.emit.apply(this, arguments); 43 44 // After all event handlers have run, run _on* handler 45 //運行完標準事件處理函數后,再來運行本身的私有函數。 46 //load和error事件處理完后觸發done事件 47 //done事件處理完畢后,再來運行本身的_ondone函數,然后觸發stop事件 48 if(this['_on' + type]){ 49 this['_on' + type].apply(this, slice.call(arguments, 1)); 50 } 51 return result; 52 } 53 }); 54 55 function notify(type, listener){ 56 // summary: 57 // Register a listener to be notified when an event 58 // in dojo/request happens. 59 // type: String? 60 // The event to listen for. Events emitted: "start", "send", 61 // "load", "error", "done", "stop". 62 // listener: Function? 63 // A callback to be run when an event happens. 64 // returns: 65 // A signal object that can be used to cancel the listener. 66 // If remove() is called on this signal object, it will 67 // stop the listener from being executed. 68 return hub.on(type, listener); 69 } 70 notify.emit = function(type, event, cancel){ 71 return hub.emit(type, event, cancel); 72 }; 73 74 // Attach notify to dojo/request/util to avoid 75 // try{ require('./notify'); }catch(e){} 76 return util.notify = notify; 77 }); View Code

  最后的一句:util.notify= notify; util將notify與provider關聯起來。

?

  registry

  該模塊可以在不同的情況下使用不同的provider;匹配的條件可以是正則表達式、字符串或者函數。通過registry可以根據不同的條件注冊不同的provider。

1 require(["dojo/request/registry", "dojo/Deferred"], function(request, Deferred){ 2 request.register("crossdomain/ie", xdrProvider); 3 4 var xdrProvider = function(url, options){ 5 var def = new Deferred(); 6 xdr = new XDomainRequest(); 7 if (xdr) { 8 xdr.onerror = function(){ 9 def.reject('error'); 10 }; 11 xdr.ontimeout = function(){ 12 def.reject('timeout'); 13 }; 14 xdr.onprogress = function(){ 15 def.progress('progress'); 16 }; 17 xdr.onload = function(res){ 18 def.resolve(res); 19 }; 20 xdr.timeout = 6000; 21 xdr.open(options.method, url); 22 xdr.send(serilize(options.data)); 23 } else { 24 def.reject("Failed to create"); 25 } 26 27 return def; 28 } 29 30 request.get("crossdomain/ie/getData", { 31 method: "get", 32 data:{id:'ie9'} 33 }).then(function(text){ 34 // Do something with the response 35 }); 36 37 }); View Code

  以下便是registry的源碼:

define(['require','../_base/array','./default!platform',//想想notify中的load函數'./util' ], function(require, array, fallbackProvider, util){var providers = [];function request(url, options){var matchers = providers.slice(0),//作用類似clonei = 0,matcher;while(matcher=matchers[i++]){if(matcher(url, options)){//匹配providerreturn matcher.request.call(null, url, options);}}//fallbackProvider由default根據不同平臺注入默認的providerreturn fallbackProvider.apply(null, arguments);}function createMatcher(match, provider){var matcher;if(provider){if(match.test){// RegExpmatcher = function(url){return match.test(url);};}else if(match.apply && match.call){matcher = function(){return match.apply(null, arguments);};}else{matcher = function(url){return url === match;};}matcher.request = provider;}else{// If only one argument was passed, assume it is a provider function// to apply unconditionally to all URLsmatcher = function(){return true;};matcher.request = match;}return matcher;}request.register = function(url, provider, first){var matcher = createMatcher(url, provider);providers[(first ? 'unshift' : 'push')](matcher);return {remove: function(){var idx;if(~(idx = array.indexOf(providers, matcher))){providers.splice(idx, 1);}}};};//這里意味著registry也可以使用插件的寫法,作用是替換一個默認的providerrequest.load = function(id, parentRequire, loaded, config){if(id){// if there's an id, load and set the fallback providerrequire([id], function(fallback){fallbackProvider = fallback;//js中的詞法作用域,load中永遠能夠訪問到fallbackProvider變量。 loaded(request);});}else{loaded(request);}};util.addCommonMethods(request);return request; }); View Code

?

  handlers

  XMLHttpRequest對象請求成功后返回的數據格式只有text跟xml兩種,handlers根據request中指定的handleAs參數將請求成功后的數據轉化為指定類型。與jquery中的類型轉化器作用類似。

  dojo中提供了以下三種數據轉化器:

  

  此外,handlers有跟registry類似的register方法,可以讓我們自定義數據轉化器。

1 require(["dojo/request/handlers", "dojo/request", "dojo/dom", "dojo/dom-construct", "dojo/json", 2 "dojo/on", "dojo/domReady!"], 3 function(handlers, request, dom, domConst, JSON, on){ 4 handlers.register("custom", function(response){ 5 var data = JSON.parse(response.text); 6 data.hello += "!"; 7 return data; 8 }); 9 10 on(dom.byId("startButton"), "click", function(){ 11 domConst.place("<p>Requesting...</p>", "output"); 12 request("./helloworld.json", { 13 handleAs: "custom" 14 }).then(function(data){ 15 domConst.place("<p>data: <code>" + JSON.stringify(data) + "</code>", "output"); 16 }); 17 }); 18 }); View Code

  

  如果您看完本篇文章感覺不錯,請點擊一下下方的推薦來支持一下博主,謝謝!

總結

以上是生活随笔為你收集整理的dojo/request模块整体架构解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产剧情在线观看 | 四虎影视免费永久大全 | 青青草97 | 蜜臀视频在线观看 | 中文字幕23 | 精品国产欧美 | 日本无遮羞调教打屁股网站 | av成人在线观看 | 国产xxxx裸体xxx免费 | 亚洲美女一级片 | 午夜精品久久99蜜桃的功能介绍 | 熟妇人妻一区二区三区四区 | 国产成人在线网站 | 欧美vieox另类极品 | 蜜臀人妻四季av一区二区不卡 | 亚洲淫片| 亚洲av日韩av不卡在线观看 | 亚洲精品乱码久久久久久按摩观 | 天天操天天舔 | 亚洲午夜精品在线 | 亚洲一区二区三区人妻 | 日本一区二区三区在线免费观看 | 国产真实老熟女无套内射 | 玩偶游戏在线观看免费 | 日本一区二区在线 | 日本国产精品视频 | h部分肌肉警猛淫文 | 麻豆av一区二区三区久久 | 久操热线| 色婷婷香蕉在线一区二区 | 青青久久久 | a视频在线观看免费 | 亚洲中文字幕久久无码 | 懂色av一区二区三区免费观看 | 91麻豆精品久久久久蜜臀 | www国产www| 精产国品一二三区 | 国产一级全黄 | 性a视频| 少妇3p视频 | 五月天堂网 | 国产一级片中文字幕 | 原神女裸体看个够无遮挡 | 青青一区二区 | 日韩视频在线观看一区二区三区 | 黑巨茎大战欧美白妞 | 亚洲 欧美 日韩 国产综合 在线 | 黑人精品一区二区三区不 | 国产靠逼视频 | 夜夜爽天天爽 | 亚洲一区 中文字幕 | 成人欧美一区二区三区黑人冫 | 曰批视频在线观看 | 手机看片福利视频 | 国产主播毛片 | 婷婷激情丁香 | 99re这里都是精品 | 97视频在线观看免费高清完整版在线观看 | 国产美女精品一区二区三区 | 中文字幕免费在线看线人 | 国产18禁黄网站免费观看 | 日本做爰三级床戏 | 日日不卡av | 日本xxx在线观看 | 欧美国产第一页 | 伊人成年网 | 国产成人精品在线观看 | 亚洲综合图色40p | 久久久无码人妻精品一区 | 亚洲AV成人无码久久 | 免费看一区二区三区 | 女的高潮流时喷水图片大全 | 国产精品久久久久久精 | 夜夜躁很很躁日日躁麻豆 | 男生捅女生肌肌 | 在线免费观看黄色 | 四虎网站在线播放 | 足交在线观看 | 国产丝袜一区二区三区 | 极品福利视频 | 亚洲综合网在线观看 | 亚洲国产成人精品视频 | 毛片日本 | 日韩五月| 婷婷久久综合 | 久久久久久久久久久久久久久久久 | 毛片女人 | 欧美国产高潮xxxx1819 | 91禁动漫在线 | 亚洲精品女 | 一区两区小视频 | 夜夜爽妓女8888视频免费观看 | 精品国产乱码久久久久久久软件 | h片在线观看 | 国产精品123区 | 色88久久久久高潮综合影院 | 日韩精品一区二区不卡 | 91精品人妻一区二区三区四区 | 色接久久 |