ajax异步实现原理
很多同学在进行编程学习时缺乏系统学习的资料。本页面基于ajax异步实现原理内容,从基础理论到综合实战,通过实用的知识类文章,标准的编程教程,丰富的视频课程,为您在ajax异步实现原理相关知识领域提供全面立体的资料补充。同时还包含 android、a href、abap 的知识内容,欢迎查阅!
ajax异步实现原理相关知识
-
异步请求原生Ajax窥探csdn发布地址http://blog.csdn.net/hope_it/article/details/72861819 简介 AJAX = 异步 JavaScript 和 XML。 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。 ajax基础 XMLHttpRequest 对象,所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象 创建 XMLHttpRequest 对象 var xhr =new XMLHttpRequest(); 老版本的 Internet Explorer
-
深入理解Ajax原理概念ajax 的全称是AsynchronousJavaScript and XML,其中,Asynchronous 是异步的意思,它有别于传统web开发中采用的同步的方式。理解同步异步异步传输是面向字符的传输,它的单位是字符;而同步传输是面向比特的传输,它的单位是桢,它传输的时候要求接受方和发送方的时钟是保持一致的。举个例子来说同步和异步,同步就好像我们买楼一次性支付,而异步就是买楼分期付款。所以当我们把这种生活中的概念化解释转移到理解Ajax异步上来就发现,它是通过这样一种异步的方式来让用户更加收益,也就是说可以让用户的有更好的体验性。其实这也是Ajax的意义所在。通过分析XmlHttpRequest来理解Ajax的原理Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。要清楚这个过程和原理,我们必须对XMLHttpRequest有所了解。XMLHttpRequest
-
同步和异步的区别? Ajax 细节问题详解Ajax 是什么? 如何创建一个Ajax?Ajax并不算是一种新的技术,全称是asychronous javascript and xml,可以说是已有技术的组合,主要用来实现客户端与服务器端的异步通信效果,实现页面的局部刷新,早期的浏览器并不能原生支持ajax,可以使用隐藏帧(iframe)方式变相实现异步效果,后来的浏览器提供了对ajax的原生支持使用ajax原生方式发送请求主要通过XMLHttpRequest(标准浏览器)、ActiveXObject(IE浏览器)对象实现异步通信效果基本步骤:var xhr =null;//创建对象 if(window.XMLHttpRequest){xhr = new XMLHttpRequest();}else{xhr = new ActiveXObject("Microsoft.XMLHTTP");} xhr.open(“方式”,”地址”,”标志位”);//初始化请求&nbs
-
asp + ajax 异步处理数据.功能背景:当用户输入用户名时,判断数据表中用户名是否已经存在。 技术手段:ajax异步请求。 其实,光说ajax 大家多少都对他有了解,但是一般都是将它运用在html中,今天我分享一下在asp中如何更好的运用ajax 在功能背景中已经介绍,当用户输入用户名时需要判断是否存在相同用户名,这里使用ajax异步调用 <script type = "text/javascript"> $("#className").focusout(function(){ var data = $("#className").attr('value'); if(data != ''){ $.ajax({ url:"checkClassName.a
ajax异步实现原理相关课程
ajax异步实现原理相关教程
- 5. Ajax 的工作原理 Ajax 相当于用户端和服务端的一个中间层,用来处理异步化的数据交互。这里涉及到两个重要的点:XMLHttpRequest 和 异步。先讲异步,异步指的是用户无需等待,异步操作不会阻碍当前用户的活动。在早期,对于我们的 Web 交互,每次用户发送请求,都会阻塞当前活动,进行页面重载。而在服务器响应请求之前,浏览器只能是一片空白。体验极其差!然而,使用异步就能够解决这个问题,浏览器端发送请求,但是不会阻塞用户当前的活动,也不会丢弃当前页面,数据一样可以进行交互和刷新。体验效果极佳!另一个 XMLHttpRequest 可以说是 Ajax 的核心技术。使用 XMLHttpRequest ,我们可以通过 JavaScript 向服务端发送请求,并且获取和处理服务端返回的数据,却不会阻塞用户活动,而仅仅只是局部动态更新,更加不会导致 web 页面频繁重载。Ajax 工作过程大致如下:JavaScript 通过 XMLHttpRequest 向后端发起异步请求,可以是 get 或者 post 等;服务端接收请求,处理并返回数据;JavaScript 通过 XMLHttpRequest 获取并解析服务端返回的数据内容;JavaScript 通过动态更新 DOM 或者执行其他操作。
- AJAX Asynchronous JavaScript + XML(异步JavaScript和XML), 其本身不是一种新技术,而是一个在 2005年被Jesse James Garrett提出的新术语,用来描述一种使用现有技术集合的‘新’方法。(MDN)AJAX 是2005年提出的一种术语,并不代表某个特定的技术。其译名 异步JavaScript和XML 描述出了核心,就是使用 JavaScript 发送异步 HTTP 请求,这样就摆脱了想要和服务端交互,必须刷新页面的痛点。学习 AJAX 相关内容前,建议有一些简单的 HTTP 相关知识的储备,否则很难理解其工作流程。
- 2. 异常处理原则 异常是程序运行过程中不可避免的问题。异常出现的原因很多,但不管怎样,都需要提前预知或者当异常发生后采取相应的处理措施。异常的处理原则是:能预知的尽可能在逻辑层面提前制止。如用户注册时,要求登录名是唯一的,可先检查数据库是否存在同名用户名后,再进行添加操作;以一种友好的方式告知使用者出错的原因;采用多层体系结构的项目中,建议异常由下逐层向上抛出,一直到达应用层面;使用日志记录功能把异常信息记录在日志文件中,便于开发者分析。如下面的控制器方法:@Controllerpublic class ExceptionAction {@RequestMapping("/exception01")public String exception01(@RequestParam("userName") String userName) { return "exception";}}在浏览器中输入:http://localhost:8888/sm-demo/exception01 ,页面中会出现错误提示。这个原因是 @RequestParam(“userName”) 注解在默认情况下,要求请求包中一定要有 userName 这个参数。显然,页面中显示出来的错误信息是不友好的。所谓的异常处理,并不能完全阻止异常的发生。而是把异常信息对外、对内做一个封装,换一个浅白的、直接的、非专业的方式告诉使用者。对于前面的异常解决方案,可以在 @RequestParam(value = “userName”,required = false) 中添加一个 required = false 的设置。这是一种最理想的异常解决方案。
- 6. Ajax 的优点 Ajax 技术的优势有如下几点:无刷新更新页面。抛弃了早期重载页面的方式,加快了请求的速度,提升了用户体验。减少客户端的内存消耗。采用更加轻量的数据提取做法,避免了客户端大量的冗余请求,减少了不必要的内存消耗。将部分传统技术中原本在服务端的工作转移到客户端来进行。 使用Ajax,一些数据的处理能够在客户端进行,减轻了服务端的压力。兼容性极好,几乎所有的浏览器都支持。不需要额外插件或者虚拟机即可使用。当然,Ajax 带来的最大的优势还是通过异步请求和处理数据的方式,取代了通过原始 Form 表单提交来更新数据及页面的方式,从而使得我们的 Web 应用成为了可能。
- 2. 实现步骤 上一节我们已经知道了 Promise 是一个类,默认接收一个参数 executor(执行器),并且会立即执行。所以首先需要创建一个 Promise 的类,然后传入一个回调函数并执行它,故有如下的初始代码:class Promise { constructor(executor) { executor(); }}Promise 有三个状态:等待(padding)、成功(fulfilled),失败(rejected)。默认是等待状态,等待态可以突变为成功态或失败态,所以我们可以定义三个常量来存放这三个状态const PENDING = 'PENDING';const RESOLVED = 'RESOLVED'; // 成功态const REJECTED = 'REJECTED'; // 失败态class Promise { constructor(executor) { this.status = PENDING; // 默认是等待态 executor(); }}这样我们就知道了 Promise 的基本状态,那内部的状态是怎么突变为成功或失败的呢?这里执行器(executor)会提供两个个方法用于改变 Promise 的状态,所以我们需要在初始化时定义 resolve 和 reject 方法:在成功的时候会传入成功的值,在失败的时候会传入失败的原因。并且每个Promise 都会提供 then方法用于链式调用。class Promise { constructor(executor) { this.status = PENDING; const resolve = (value) => {}; const reject = (reason) => {}; // 执行executor时,传入成功或失败的回调 executor(resolve, reject); } then(onfulfilled, onrejected) { }}这时我们就可以开始着手去更改 Promise的状态了,由于默认情况下 Promise 的状态只能从 pending 到 fulfilled 和 rejected 的转化。class Promise { constructor(executor) { this.status = PENDING; const resolve = (value) => { // 只有等待态时才能更改状态 if (this.status === PENDING) { this.status = RESOLVED; } }; const reject = (reason) => { if (this.status === PENDING) { this.status = REJECTED; } }; executor(resolve, reject); } ...}成功和失败都会返回对应的结果,所以我们需要定义成功的值和失败的原因两个全局变量,用于存放返回的结果。class Promise { constructor(executor) { this.status = PENDING; this.value = undefined; this.reason = undefined; const resolve = (value) => { // 只有等待态时才能更改状态 if (this.status === PENDING) { this.value = value; this.status = RESOLVED; } }; const reject = (reason) => { if (this.status === PENDING) { this.reason = reason; this.status = REJECTED; } }; executor(resolve, reject); } ...}这时我们就已经为执行器提供了两个回调函数了,如果在执行器执行时抛出异常时,我们需要使用 try…catch 来补货一下。由于是抛出异常,所以,需要调用 reject 方法来修改为失败的状态。try { executor(resolve, reject);} catch(e) { reject(e)}我们知道实例在调用 then 方法时会传入两个回调函数 onfulfilled, onrejected 去执行成功或失败的回调,所以根据状态会调用对应的函数来处理。then(onfulfilled, onrejected) { if (this.status === RESOLVED) { onfulfilled(this.value) } if (this.status === REJECTED) { onrejected(this.reason) }}这样我们就完了 Promise 最基本的同步功能,let promise = new Promise((resolve, reject) => { resolve('value'); // throw new Error('错误'); // reject('error reason') // setTimeout(() => { // resolve('value'); // }, 1000)})promise.then((data) => { console.log('resolve response', data);}, (err) => { console.log('reject response', err);})用上面的代码对我们写的 Promise 进行验证,通过测试用例可知,我们写的 Promise 只能在同步中运行,当我们使用 setTimeout 异步去返回时,并没有预想的在then的成功回调中打印结果。对于这种异步行为需要专门处理,如何处理异步的内容呢?我们知道在执行异步任务时 Promise 的状态并没有被改变,也就是并没有执行 resolve 或 reject 方法,但是 then 中的回调已经执行了,这时就需要增加当 Promise 还是等待态的逻辑,在等待态时把回调函数都存放起来,等到执行 resolve 或 reject 再依次执行之前存放的then的回调函数,也就是我们平时用到的发布订阅模式。实现步骤:首先,需要在初始化中增加存放成功的回调函数和存放失败的回调函数;然后,由于是异步执行 resolve 或 reject 所以需要在 then 方法中把回调函数存放起来;最后,当执行 resolve 或 reject 时取出存放的回调函数依次执行。根据以上的实现步骤可以得到如下的代码:class Promise { constructor(executor) { this.status = PENDING; this.value = undefined; // 成功的值 this.reason = undefined; // 失败的原因+ // 存放成功的回调函数+ this.onResolvedCallbacks = [];+ // 存放失败的回调函数+ this.onRejectedCallbacks = []; let resolve = (value) => { if (this.status === PENDING) { this.value = value; this.status = RESOLVED;+ // 异步时,存放在成功的回调函数依次执行+ this.onResolvedCallbacks.forEach(fn => fn()) } }; let reject = (reason) => { if (this.status === PENDING) { this.value = reason; this.status = REJECTED;+ // 异步时,存放在失败的回调函数依次执行+ this.onRejectedCallbacks.forEach(fn => fn()) } }; try { executor(resolve, reject); } catch(e) { reject(e) } } then(onfulfilled, onrejected) { if (this.status === RESOLVED) { onfulfilled(this.value) } if (this.status === REJECTED) { onrejected(this.reason) }+ if (this.status === PENDING) {+ this.onResolvedCallbacks.push(() => {+ // TODO+ onfulfilled(this.value);+ })+ this.onRejectedCallbacks.push(() => {+ // TODO+ onrejected(this.reason);+ })+ } }}上面的代码中,在存放回调函数时把 onfulfilled, onrejected 存放在一个函数中执行,这样的好处是可以在前面增加处理问题的逻辑。这样我们就完成了处理异步的 Promise 逻辑。下面是测试用例,可以正常的执行 then 的成功回调函数。let promise = new Promise((resolve, reject) => { setTimeout(() => { resolve('100'); }, 1000)})promise.then((data) => { console.log('resolve response:', data); // resolve response: 100}, (err) => { console.log('reject response:', err);})到这里我们是不是已经基本实现了 Promise 的功能呢?ES6 中的 then 方法支持链式调用,那我们写的可以吗?我们在看下面的一个测试用例:let promise = new Promise((resolve, reject) => { setTimeout(() => { resolve('100'); }, 1000)})promise.then((data) => { console.log('resolve response:', data); // resolve response: 100 return 200}, (err) => { console.log('reject response:', err);}).then((data) => { console.log('data2:', data)}, null)// TypeError: Cannot read property 'then' of undefined然而当我们在执行的时候会报错,then 是 undefined。为什么会这样呢?那我们要知道如何满足链式调用的规范,那就是在完成任务后再返回一个Promise 实例。那如何返回一个 Promise 实例呢?在 Promise A+ 规范的 2.2.7 小节在有详细的描述,再实例化一个 promise2 来存放执行后的结果,并返回 promise2。那么我们就要改造 then 方法了。class Promise { ... then(onfulfilled, onrejected) { let promise2 = new Promise((resolve, reject) => { if (this.status === RESOLVED) { const x = onfulfilled(this.value) resolve(x) } if (this.status === REJECTED) { const x = onrejected(this.reason); reject(x) } if (this.status === PENDING) { this.onResolvedCallbacks.push(() => { const x = onfulfilled(this.value) resolve(x) }) this.onRejectedCallbacks.push(() => { const x = onrejected(this.reason); reject(x) }) } }) return promise2 }}再使用上面的测试用例,就可以得到正确的结果:let promise = new Promise((resolve, reject) => { resolve('100');})promise.then((data) => { console.log('data1:', data); // data1: 100 return 200}, null).then((data) => { console.log('data2:', data); // data2: 200 throw new Error('error')}, null).then(null, () => { consol.log('程序报错...')})上面的测试用例中,当 then 的回调函数抛出异常时需要去捕获错误,传到下一个 then 的失败回调函数中。class Promise { ... then(onfulfilled, onrejected) { let promise2 = new Promise((resolve, reject) => { if (this.status === RESOLVED) { try{ const x = onfulfilled(this.value) resolve(x) } catch(e) { reject(e) } } if (this.status === REJECTED) { try{ const x = onrejected(this.reason); resolve(x) } catch(e) { reject(e) } } if (this.status === PENDING) { this.onResolvedCallbacks.push(() => { try{ const x = onfulfilled(this.value) resolve(x) } catch(e) { reject(e) } }) this.onRejectedCallbacks.push(() => { try{ const x = onrejected(this.reason); resolve(x) } catch(e) { reject(e) } }) } }) return promise2 }}到这里为止我们就已经实现了一个简版的 Promise,因为Promise是一个规范,很多人都可以实现自己的 Promise 所以 Promise A+ 规范做了很多兼容处理的要求,如果想实现一个完整的 Promise 可以参考 Promise A+ 规范 。
- 实现 ajax function ajax(options) { const { url, method, data, params, success, error } = options; const xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { // readyState为4的时候已接收完毕 if (xhr.readyState === 4) { // 状态码200表示成功 if (xhr.status === 200) { console.log(xhr.responseText); success.call(this, xhr.responseText); } else { console.log(xhr.status); error.call(this, xhr.status) } } }; // get 请求 if (method === 'get' || method === 'GET') { if (typeof params === 'object') { // params拆解成字符串 params = Object.keys(params).map(function (key) { return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]); }).join('&'); } url = params ? `${url}?${params}` : url; xhr.open(method, url, true); xhr.send(); } // post 请求 if (method === 'post' || method === 'POST') { xhr.open(method, url, true); xhr.setRequestHeader("Content-type", "application/json; charset=utf-8"); xhr.send(JSON.stringify(params)); }}使用 promise 进行封装function ajax(url, method, params) { return new Promise((resolve, reject) => { // 创建XMLHttpRequest对象 const xhr = new XMLHttpRequest(); // 状态改变时的回调 xhr.onreadystatechange = function () { // readyState为4的时候已接收完毕 if (xhr.readyState === 4) { // 状态码200表示成功 if (xhr.status === 200) { resolve(xhr.responseText); } else { reject(xhr.status); } } }; // ... });}
ajax异步实现原理相关搜索
-
ajax
android
a href
abap
abap开发
abort
absolutelayout
abstractmethoderror
abstracttablemodel
accept
access
access教程
accordion
accumulate
acess
action
actionform
actionlistener
activity
addeventlistener