日期:2014-05-16  浏览次数:20727 次

dojo(四):ajax请求

储备知识

1、在介绍新版本的ajax请求之前,需要先了解一些dojo/Deferreds。

       初次听到“Deferred”这个概念,可能会觉得这是一个神秘的东西。实际上它在执行异步操作的时候非常强大,例如执行Ajax请求。简单来说,Deferred会延迟一段时间再执行某些操作;最重要的,它可以实现等待一个前置动作完成之后才执行你指定的动作。Ajax就是这样一个例子。我们希望在服务器成功返回我们需要的信息之后才执行某些动作。这种情况下,等待返回值是非常重要的。 

       Dojo实现的可延迟执行的对象是dojo/Deferred(0.3版本就有,并且在1.8版本中进行了重构).实例化一个Deferred对象之后,可以通过向then方法传递一个函数来注册一个动作或者称为回调,这个函数会在Deffered被解析后(调用deffered.resolve)被调用。then方法接收的第二个参数也是一个函数,这个函数会在Deffered被拒绝(deffered.reject)之后调用。让我们来看一个例子。

   

<div id="respId"></div>
	 <button id="resolveId">Resolved</button>
	 <button id="rejectId">Rejected</button>
	 
	 <script src="dojo-release-1.9.1/dojo/dojo.js" data-dojo-config="async:true"></script>
	 <script>
	     require(["dojo/on","dojo/dom","dojo/Deferred","dojo/domReady!"],
	     function(on,dom,Deferred){
	    	 //实例化一个可延迟执行动作的对象Deferred
	    	 var deferred = new Deferred();
	    	 //注册接收和拒绝后的动作
	    	 deferred.then(function(resolveText){
	    		 dom.byId("respId").innerHTML = resolveText;
	    	 },function(rejectText){
	    		 dom.byId("respId").innerHTML = rejectText;
	    	 });
	    	 
	    	 //触发接收resolve()方法:Resolve the deferred, putting it in a success state.
	    	 on(dom.byId("resolveId"),"click",function(evt){
	    		 deferred.resolve("Yes, it is resolved.");
	    	 });
	    	 //触发拒绝reject()方法:Reject the deferred, putting it in an error state.
	    	 on(dom.byId("rejectId"),"click",function(evt){
	    		 deferred.reject("Oh,no.it is rejected.");
	    	 });
	     });
         上面的例子,当我们点击Resolved按钮或者Rejected按钮之后,在deferred对象的then方法中注册的相应事件就会被调用。而且我们会发现,两个按钮只有第一次被点击的那个生效,以后点击不生效了。也就是说在then方法中注册的两个回调方法只会有一个被执行(一个在成功之后执行,一个在拒绝之后执行),并且只能执行一次。

2、 dojo/promise

       promise是代表某个操作返回的事件发生结果的对象,例如ajax请求返回的对象,包括状态(成功或失败)和数据(响应或失败信息);它有以下几个特点:

  • 处在unfulfilled,resolved,rejected中的某一个状态上
  • 状态可以从unfulfilled变化到resolved上,或者从unfulfilled变化到rejected上
  • 实现then方法来注册在状态发生改变时的回调函数
  • 回调函数不能改变promise的返回值(即回调函数里面不会改变传入进来的参数值,但是可以返回新的值,以提供链式操作) 
  • promise的then方法返回一个新的promise,以提供链式操作;同时,保持原来的promise的值不变。
        dojo/promise/all

        dojo/promise/all替换dojo/DeferredList,提供了一个管理多个异步处理的机制,通过把几个promise合并为一个promise。有些时候,你可能需要平行的(或者说同时)从多个资源处获取数据,并且希望在所有的请求都结束之后能够通知你进行其他操作,使用dojo/promise/all就可以实现。可以通过传入一个或者一组Deferred到dojo/promise/all的构造器来使用dojo/promise/all。返回的结果是:如果是传入单一对象,结果和传入对象一样;如果是传入一组对象,结果是按照传入顺序的一个数组。例如传入A,结果就是A;传入[A,B],结果就是包含A,B的一个数组。我们来看一个例子: 

require(["dojo/promise/all", "dojo/Deferred", "dojo/request", "dojo/_base/array", "dojo/dom-construct", "dojo/dom", "dojo/json", "dojo/domReady!"],
function(all, Deferred, request, arrayUtil, domConstruct, dom, JSON){
    var usersDef = request.get("users.json", {
        handleAs: "json"
    }).then(function(response){
        var users = {};
 
        arrayUtil.forEach(response, function(user){
            users[user.id] = user;
        });
 
        return users;
    });
 
    var statusesDef = request.get("statuses.json", {
   &nb