-
Notifications
You must be signed in to change notification settings - Fork 15
ajax
与Zepto相比,由于Neat是移动端优先的,对dom操作进行了弱化同时,但对网络和异步支持进行了增强(当然, jQuery也不错,Neat也是借鉴了jQuery)。而网络主要就是ajax,Neat对ajax支持非常强大与灵活,和zepto不同的是,Neat ajax是建立在Neat的promise/deferred之上(如果你还不了解,先不用着急,后续会有介绍),这会使编码变的非常愉快,Neat在ajax 支持上秒杀zepto, 下面我们看一个输出当前页面源码的简单的例子:
function log(data){
console.log(data);
}
$.get("").done(log)
搞定,简单吧,我们也可以用post方法:
$.post("").done(log)
正如其名所示,两者唯一的区别就是http请求的method不同,前者是"GET",后者是"POST"。其实
$.ajax("",{},{type: "get"})
.done(log)
下面我们来详细探索一下neat ajax的全部功能:
- url:请求资源的url地址,为空字符串时则为当前页面
- data:请求的参数,类型为对象。
- options: 请求的可选配置,注:$.get和$.post没有此参数。
- 返回值:一个扩展后的promise对象(后续会有专门介绍)
我们先来看一个带参数的请求:
$.ajax("",{name:"Davin",age:"18"},{type: "get"})
.done(log)
//实际的请求链接会自动添加:"?name=Davin&age=18"
如果type是post,则参数会在http header中发送。
-
功能:设置ajax请求成功后回调
-
callback(data): data 为请求到的数据,此时回调函数上下文this 为当前的XMLHttprequest对象。
注:所有ajax 请求回调的上下文对象都为当前请求的原始XMLHttprequest对象,下面将不再做特殊说明。
我们可以为一个ajax添加多个完成回调:
$.ajax("")
.done(log)
.done(function(d){
alert(d)
//会输出xhr对象
log(this)
})
neat会将请求到的数据分别传递到每个成功回调当中,你可以进行多种处理,但有时我们需要对数据进行链式处理,即:第一步处理后的数据,传递给第二个函数,以此类推,这时我们可以使用then方法:
callbacks为回调列表,分别为成功回调、失败回调、异常回调,then是promise中非常强大的一个方法,可以顺序执行异步任务,是异步任务同步化的重要接口,详细介绍我们放到后面promise/deferred章节中,在此只做简单示例,有个概念即可:
$.ajax("")
.then(function(data){
return data.substr(0,20)
})
.then(function(d){
console.log(d)
//handle the data
})
上面示例中我们将返回的内容先截取20个字符,然后再输出。可见,采取这种方式,你可以清晰的组织自己的处理代码。
如果网络请求发生错误,如断网,或服务器没有找到请求的资源,我们可以在fail中处理错误:
- callback(status): status为失败时的http 状态码:
$.ajax("xxx")
.done(log)
.fail(function(status){
console.log(status)
})
//会输出404,服务器上当前文件夹没有名为xxx的文件
如果请求成功,则调用done;如果失败,则会调用fail,此时neat会将失败时的 http 状态码 传给fail,也可以使用this, 即xhr对象,可以通过它获取更多的信息。fail回调和done一样,也可以指定多个。
Neat提供了优雅的异常处理机制:如果监听链,即处理逻辑链条,也就是你传递的done、fail回调中发生异常时,可以统一捕获并处理:
- callback(error): error为异常对象。
$.ajax("")
.done(function(data){
//我们故意触发一个异常
xxx
})
.done(function(data){
console.log(data) //1
})
.catch(function(e){
console.log(e)
})
执行后会输出:
ReferenceError: xxx is not defined(…)
注:一旦异常发生,未执行的回调都会终止,所以上面1处代码不会执行,如果catch函数中再抛出异常,neat 会将异常抛出,将不再自动处理,这也就意味着后续的catch回调将中断,同时浏览器控制台会输出错误报告,这样则不会影响调试。
有些时候,无论网络任务是否成功,我们都希望在结束时执行某个回调,此时可以使用always:
- callback(data): 成功时data为请求到的数据,失败时为http请求的状态码(和fail相同)
$.ajax("xxx")
.always(function(mix){
console.log(mix)
})
如果请求成功,mix为请求到的数据,如果失败,则为失败时的 xhr。一般情况下,使用的姿势会是这样:
//记录请求次数
var reqTimes=0
$.ajax("xxx")
.done(handler)
.fail(handler)
.always(function(d){
++reqTimes
})
注:为了让异常处理分离,如果调用链中触发了未捕获的异常,always不会被调用。也就是上面代码中done或fail的回调中如果抛出异常,always不会被调用。请在catch中处理异常。
现在思考一个问题,如果要用 ajax请求一个比较大的文件,请求过程可能会比较耗时,为了给用户提供一个友好的反馈,需要提供一个加载进度条,此时progress将非常方便:
- 功能:用于监听当前请求的进度
- callback(ProgressEvent): Progress Event的介绍请移步 w3.org progress-event .下面是一个输出加载进度的简单示例。
$.get("bigfile.json")
.done(handler)
.progress(function(pe){
if(pe.lengthComputable) {
console.log(pe.loaded/pe.total*100+"%");
}
})
其中bigfile.json为当前路径下的一个大文件,在请求的过程中控制台会输出不同时段的进度,你可以提供一个进度条进行展示。当然,这只是一个简单使用示例,对其详细的介绍将在后面promise章节中。
一般业务,上面的工具已经足矣应对大部分场景,但是总有时候,我们需要更多的功能。neat提供了最大的灵活性,可以让你控制 http请求头
此参数只有$.ajax方法有,$.get 、$.post并没有提供,如果需要设置options,请直接调用$.ajax。 options主要有两部分构成: type、header
- type:值为"get"或"post",用于设置http请求的方法。
- header :http请求头字段,是一个对象,可以通过此参数自定义任意合法的http请求头字段,详细的请求头字段列表请移步 w3 Http request fileds
下面我们看一个例子:
$.ajax("", {}, {
type: "post",
header: {
"accept":"application/xml, text/javascript, */*;"
}
}).done(function (d){
log("done ")
})
浏览器的request header中accept字段设置为:
"application/xml, text/javascript, */*;"
var ajax=$.ajax("")
ajax.done(log).fail(log)
//终止请求
ajax.xhr.abort()
//获取请求url
ajax.xhr.responseURL
我们也可以通过xhr对象添加一些其它事件回调:
所有XMLHttpRequest对象支持的回调(名称以on开头),各个浏览器支持可能有差别,下面是chrome支持的。 onabort onerror onload onloadend onloadstart onprogress onreadystatechange ontimeout
ajax.xhr.onabort=function(){
//do something on abort
}
您可以提供任意一个回调。注意,不要设置onreadystatechange、onprogress回调,因为neat ajax底层会设置这两个回调,会将你设置的回调覆盖掉.
综上所述,相信你已经看到了,neat的ajax不仅强大,而且灵活。 用过zepto的相信已经对neat心动了。和Zepto相比,neat在控制http请求和处理回调上非常灵活。 Neat 抛弃了jQuery ajax的全局设置及钩子,鸡肋,弃之。当然,neat的数据获取和异步处理的强大远不止于此,本文中还有很多没涉及到的点。先挖两个坑如下题:
- 如果有好几个网络请求,每一步的请求都依赖于前一步的结果,用ajax怎么做?
- 如果要在多个网络请求都完成之后再做一些事,应该怎么做?
所有的答案都在promise章节。沐浴焚香更衣后出门向后就是了😄。