储备知识

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", {
        handleAs: "json"
    });
    all([usersDef, statusesDef]).then(function(results){
        var users = results[0],
            statuses = results[1],
            statuslist = dom.byId("statuslist");
 
        if(!results[0] || !results[1]){
            domConstruct.create("li", {
                innerHTML: "An error occurred"
            }, statuslist);
            return;
        }
        arrayUtil.forEach(statuses, function(status){
            var user = users[status.userId];
            domConstruct.create("li", {
                id: status.id,
                innerHTML: user.name + ' said, "' + status.status + '"'
            }, statuslist);
        });
    });
});

Ajax正文

4、dojo通过dojo/request来实现Ajax请求,先来看一个简单的例子

require(["dojo/request"], function(request){
    request("helloworld.txt").then(
        function(text){
            console.log("The file's content is: " + text);
        },
        function(error){
            console.log("An error occurred: " + error);
        }
    );
});

所有的Ajax方法返回的都是一个dojo/Deferred对象,我们可以在这个Deferred对象的then方法中注册回调函数。当Ajax请求成功后,dojo会帮我们调用这个Deferred的对象的resolve对象,继而会执行我们注册的响应成功的回调函数;当Ajax请求失败后,dojo会帮我们调用这个Deferred对象的rejected对象,继而执行我们注册的响应失败的回调函数。

We开发者需要他们的工具具有可扩展性以应对各种各样的环境,这样他们才会在项目组使用它,dojo/request的api正好具有这样的特点。第一个、必需的参数是请求的URL。第二个参数是一个包含请求选项的对象(非必需)。常用的选项有下面几个:

  • method--代表HTTP方法的大写字符串。dojo提供了几个帮助函数来更方便的指定这个选项(request.get,request.post,request.put,request.del)。
  • sync--布尔值。true:同步请求方式,请求阻塞知道服务区返回响应或者超时;fasle:异步请求方式。
  • query--附加在URL后面的查询参数,可以是一个字符串或者键值对。
  • data--字符串或者键值对,或者FormData对象,它们包含要发送给服务器的数据。
  • handleAs--代表如何转化服务器响应中负载(或者叫响应数据)的字符串。经过转化的服务器响应数据才会传递给回调函数。可能的格式是“text"(默认值),"json","javascript"和”xml"。
  • headers--包含请求头的键值对。

    让我们来看一个例子:

    require(["dojo/request"], function(request){
    request.post("post-content.php", {
    data: {
    color: "blue",
    answer: 42
    },
    headers: {
    "X-Something": "A value"
    }
    }).then(function(text){
    console.log("The server returned: ", text);
    });
    });

    如果我们需要处理服务器返回的响应头怎么办?为了获取响应头,我们可以使用promise.response.header(dojo.request返回的promise没有这个属性)。另外,使用promise.response.then的时候,响应(传递到回调函数里面的参数)不是服务器返回的数据,而是一个具有data属性的对象。我们来看一个例子:

    require(["dojo/dom", "dojo/on", "dojo/request", "dojo/dom-form"],
        function(dom, on, request, domForm){
            // Results will be displayed in resultDiv
     
            var form = dom.byId('formNode');
     
            // Attach the onsubmit event handler of the form
            on(form, "submit", function(evt){
     
                // prevent the page from navigating after submit
                evt.stopPropagation();
                evt.preventDefault();
     
                // Post the data to the server
                var promise = request.post("../resources/php/login-demo.php", {
                    // Send the username and password
                    data: domForm.toObject("formNode"),
                    // Wait 2 seconds for a response
                    timeout: 2000
                });
     
                // Use promise.response.then, NOT promise.then
                promise.response.then(function(response){
     
                    // get the message from the data property
                    var message = response.data;
     
                    // Access the 'Auth-Token' header
                    var token = response.getHeader('Auth-Token');
     
                    dom.byId('svrMessage').innerHTML = message;
                    dom.byId('svrToken').innerHTML = token;
                });
            });
        }
    );

JSONP (Javascript Object Notation with Padding)

Ajax请求被限制在同一个域。如果需要向一个不同的域请求数据,可以使用JSONP。

AJAX requests are restricted to the current domain. If you need to request data from a different domain, you can use JSONP. When using JSONP, a script tag is inserted in the current page, thesrc file is requested, the server wraps the data in a callback function, and when the response is interpreted, the callback is called with the data as its first argument. JSONP requests are made withdojo/request/script.

dojo(四):ajax请求的更多相关文章

  1. {Django基础七之Ajax} 一 Ajax简介 二 Ajax使用 三 Ajax请求设置csrf_token 四 关于json 五 补充一个SweetAlert插件(了解)

    Django基础七之Ajax 本节目录 一 Ajax简介 二 Ajax使用 三 Ajax请求设置csrf_token 四 关于json 五 补充一个SweetAlert插件(了解) 一 Ajax简介 ...

  2. {Django基础七之Ajax} 一 Ajax简介 二 Ajax使用 三 Ajax请求设置csrf_token 四 关于json 五 补充一个SweetAlert插件(了解)

    {Django基础七之Ajax} 一 Ajax简介 二 Ajax使用 三 Ajax请求设置csrf_token 四 关于json 五 补充一个SweetAlert插件(了解)   Django基础七之 ...

  3. 深入理解ajax系列第四篇——请求实例

    前面的话 在使用ajax的过程中,常用的请求方式是GET和POST两种.本文将以实例的形式来详细说明这两种请求方式 GET GET是最常见的请求类型,最常用于向服务器查询某些信息.必要时,可以将查询字 ...

  4. 详解Ajax请求(四)——多个异步请求的执行顺序

    首先提出一个问题:点击页面上一个按钮发送两个ajax请求,其中一个请求会不会等待另一个请求执行完毕之后再执行? 答案是:不会,这两个异步请求会同时发送,至于执行的快与慢,要看响应的数据量的大小及后台逻 ...

  5. 从零开始学 Web 之 Vue.js(四)Vue的Ajax请求和跨域

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  6. ajax请求的异步嵌套问题分析

    (本文章以as3代码为例) 问题的产生 在前端开发时,经常会使用到Ajax(Asynchronous Javascript And XML)请求向服务器查询信息(get)或交换数据(post),aja ...

  7. extjs ajax请求与struts2进行交互

    sencha extjs 5 增加一个struts2的配置,这样可以在设置好前台布局之后,与后台交互获取数据显示.现在有一个问题是struts2对于url的跳转action支 持比较良好,但是对于像E ...

  8. javascript版Ajax请求

    什么是Ajax请求,Ajax也就是“Asynchronous JavaScript and XML”(异步JavaScript和XML),无刷新数据读取.能减少流量的消耗,也提高了浏览的流畅性,给用户 ...

  9. AJAX请求和跨域请求详解(原生JS、Jquery)

    一.概述 AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. AJAX = 异步 JavaScript 和 XML,是一种用于创建快速动态网页的技术.通过在后台与服务器进行少量数 ...

随机推荐

  1. js设置datagriad的行移动

    //                    ,//                formatter: function(value,row,index){//                    ...

  2. I.MX6 PMU MMPF0100 driver porting

    /************************************************************************** * I.MX6 MMPF0100 driver ...

  3. MATLAB函数表(转自:http://bbs.06climate.com/forum.php?mod=viewthread&tid=16041&extra=page%3D4)

    MATLAB函数表 4.1.1特殊变量与常数 ans 计算结果的变量名 computer 确定运行的计算机 eps 浮点相对精度 Inf 无穷大 I 虚数单位 inputname 输入参数名 NaN ...

  4. 《深入Java虚拟机学习笔记》- 第12章 整数运算

    Java虚拟机提供几种进行整数算术运算的操作码,他们执行基于int和long类型的运算.当byte.short和char类型值参与算术运算时,首先会将它们转换为int类型.这些操作码都不会抛出异常,溢 ...

  5. ccr test

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  6. Apache log4cxx用法

    一个好的系统通常需要日志输出帮助定位问题 .Apache基金会的log4cxx提供的完善的Log分级和输出功能.所以准备把该Log模块加入的系统中. 使用log4cxx需要满足一下功能: 1.提供日志 ...

  7. lightoj 1017

    思路:动态规划,设dp[i][j]表示在前j个dusts中用了i刷子刷掉dusts的个数:状态转移方程就是: dp[i][j] = max(dp[i][j-1], dp[i-1][j-len[j]] ...

  8. eclipse+xdebug

    root@leeyoung-Satellite-M300:/etc/apache2/sites-available# nano 000-default.conf <IfModule dir_mo ...

  9. devexpress 中Grid 的使用:为零不显示

    如果要让为0的列不显示: this.gridColumn_FAmount.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric; ...

  10. [RQNOJ313]波浪数

    题目描述 波浪数是在一对数字之间交替转换的数,如1212121,双重波浪数则是指在两种进制下都是波浪数的数,如十进制数191919是一个十进制下的波浪数,它对应的十一进制数121212也是一个波浪数, ...