关于异步请求的一些事
先看这样一个例子:
function foo() {var result;$.ajax({url: '...',success: function(response) {result = response;}});return result;
}var result = foo(); // It always ends up being `undefined`.
在这个例子中,使用ajax进行异步请求,但是响应的返回值始终是undefined。那这是什么原因呢?这个问题最初也让我很困惑。下面我们来分析一下原因。
找出问题的原因
我们知道ajax中的a代表异步,那就意味着发送请求(亦或是接受响应)需要花费一点时间。而在上述例子中,$.ajax
是被立即返回的,return result;
这句语句在success
函数返回响应前就已经被执行了。主要原因还是没有理解异步和同步之间的区别。
下面这个类比希望可以使同步和异步的区别更清晰。
Synchronous(同步流)
想象你给你的一个朋友打电话,你希望他可以帮你一个忙,你会进行一段时间的等待,直到他的回答。
那么在正常同步流的代码中也会发生一样的事情。
function findItem() {var item;while(item_not_found) {// search}return item;
}var item = findItem();// Do something with item
doSomethingElse();
执行 findItem
需要花费一段时间,所有在 var item = findItem();
这条语句之后的代码都需要等待函数返回结果。
Asynchronous(异步流)
同样你又给你的朋友打了一个电话,但是现在你很忙,你给你的朋友留言让他给你回一个电话,然后你挂掉电话就做其他的事情了,直到你的朋友回你电话,你才会停下手中的事情处理这个电话。
这也正是ajax请求的过程。
findItem(function(item) {// Do something with item
});
doSomethingElse();
不去等待响应而是立即继续执行ajax之后的语句。而为了得到响应我们会定义一个回调函数,一旦收到响应就会执行这个回调函数。但是注意在ajax请求之后的语句会在回调函数调用前被执行。
解决问题的方法
1. 使用回调函数
上面的例子中
var result = foo();
// Code that depends on 'result'
改为
foo(function(result) {// Code that depends on 'result'
});
然后我们给 foo
传递函数参数
function myCallback(result) {// Code that depends on 'result'
}foo(myCallback);
函数 foo
定义如下
function foo(callback) {$.ajax({// ...success: callback});
}
一旦ajax
请求成功,$.ajax
就会调用callback
函数并且将响应传递给callback
函数。
2.使用promise
Promise API是ES6新特性之一,但是各大浏览器已经有了很好的支持(IE11及以上支持)。MDN这么定义它:
Promise 对象用于异步计算。一个 Promise 表示一个现在、将来或永不可能可用的值
promise的语法:
new Promise(/* executor */function(resolve, reject) {...}
);
这里是一段使用promise
的例子:
function delay() {// `delay` returns a promisereturn new Promise(function(resolve, reject) {// Only `delay` is able to resolve or reject the promisesetTimeout(function() {resolve(42); // After 3 seconds, resolve the promise with value 42}, 3000);});
}delay().then(function(v) { // `delay` returns a promiseconsole.log(v); // Log the value once it is resolved
}).catch(function(v) {// Or do something else if it is rejected // (it would not happen in this example, since `reject` is not called).
});
结合ajax
使用:
function ajax(url) {return new Promise(function(resolve, reject) {var xhr = new XMLHttpRequest();xhr.onload = function() {resolve(this.responseText);};xhr.onerror = reject;xhr.open('GET', url);xhr.send();});
}ajax("/echo/json").then(function(result) {// Code depending on result
}).catch(function() {// An error occurred
});
这里有关于promise
的更多信息。
3.jQuey: 使用延迟函数
jQery的延迟函数和promise
很像,但是API略有不同。每一个jQery的ajax方法都会返回一个延迟函数。
function ajax() {return $.ajax(...);
}ajax().done(function(result) {// Code depending on result
}).fail(function() {// An error occurred
});
始终要牢记promise
和延迟函数都只有一个存有未来值 的容器而不是值本身。看下面的例子:
function checkPassword() {return $.ajax({url: '/password',data: {username: $('#username').val(),password: $('#password').val()},type: 'POST',dataType: 'json'});
}if (checkPassword()) {// Tell the user they're logged in
}
这段代码就误解了异步和延迟过程,$.ajax()
会向服务器发送对/password
的请求,jQery内部机制会立即会返回一个ajax延迟函数,而这个并不是服务器发回来的响应。这也就意味着下面的判断语句(if)始终都是true,程序会认为读者已经登录,而这是不正确的。
我们可以进行一个小的修改:
checkPassword()
.done(function(r) {if (r) {// Tell the user they're logged in} else {// Tell the user their password was bad}
})
.fail(function(x) {// Tell the user something bad happened
});
现在我们仍然会向服务器发起请求,$.ajax()
也会立即返回一个延迟对象,但是我们通过监听.done()
和.fail()
事件能正确处理服务器返回的响应。.done()
事件被调用时,服务器返回的是一个正常的响应(http 200),我们通过检查他的返回对象是否为true判断用户是否登陆。
.fail()
处理函数是处理一些错误的事件。例如用户网络断开或服务器错误等。
本文代码均来自StackOverflow上这个话题。
转载于:https://www.cnblogs.com/syqcoding-life/p/9821762.html
关于异步请求的一些事相关推荐
- 架构设计|异步请求如何同步处理?
来自:程序通事 本文创意来自一次业务需求,这次需要接入一个第三方外部服务.由于这个服务只提供异步 API,为了不影响现有系统同步处理的方式,接入该外部服务时,应用对外屏蔽这种差异,内部实现异步请求同步 ...
- 异步请求 ajax的使用详解
异步交互和同步交互 要说Ajax就不得不说,异步传输和同步传输了. 异步是值:发送方发出数据后,不等接收方发回响应,接着发送下一个数据包的通讯方式. 同步是指:发送方发出数据后,等待接收方发回响应以后 ...
- 动手撸一个金馆长表情库——爬虫及异步请求
前言:对于一些社交达人,微信或者QQ斗图几乎家常便饭.然而许多人手机里却只有那么几个表情,这样怎么在表情大战中取胜呢?不过不要忘了,我们是程序猿,没有弹药库自己造呗!于是就有了这篇文章. 项目gith ...
- http异步请求方式
问题来了: 上一篇文章讲解了http的同步请求,如果需要在主线程中做多个http同步请求,必定阻塞耗费大量的时间,严重影响用户体验.那么问题来了,该如何解决呢? 解决方案: 此时我们可以将http同步 ...
- php处理异步请求_php的异步请求操作
php的异步请求操作 PHP #异步请求2012-04-15 00:21 在很多情况下,有这样的一个需求:让php在后台执行某个程序,但要让页面快速的输出显示. 以下是我总结的几种实现方式 exec ...
- JSD-2204-同步和异步请求-Ajax-Day13
1.同步请求和异步请求 同步: 指单线程依次做几件事 异步: 指多线程同时做几件事 同步请求: 指客户端只有一个主线程,既要负责页面展示相关也要负责发请求获取数据, 由于只有一个线程当发出请求时则不再 ...
- 同步请求和异步请求(利用axios)
文章目录 同步请求和异步请求 客户端如何发出异步请求? GET和POST 选择 利用GET方式 异步请求Get 运行环境环境:springboot+SpringMVC+Mybatis+vue 前端 后 ...
- iOS 中的网络请求 (同步请求、异步请求、GET请求、POST请求)
1.同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作, 2.异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然 ...
- 第106天:Ajax中同步请求和异步请求
同步请求和异步请求的区别 1.同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式. 用户填写所有信息后,提交给服务器,等待服务器的回应(检验数据),是一次性的.信息错误又要重新 ...
最新文章
- .NET之生成数据库全流程
- ZeroC ICE源代码中的那些事 - 嵌套类和局部类
- VMware的CentOS部署环境
- 190719每日一句
- 基于STM32单片机设计指纹考勤机+上位机管理
- java生成背景透明的png图片,Java生成背景透明的png图片
- 【Unity】在Scene窗口中发射射线
- 无盘服务器4根网线雨两根网线的区别,网线接法的描述:实际用到4根。
- Python-猫耳MF
- Python(八)阶段小结
- java基础-取余数,取商
- 手机支付:合作之路才是正途
- 安卓搭建http服务器——NanoHttpd
- otter异常——zookeeper重新初始化
- 2022年全球市场硬化疗法总体规模、主要企业、主要地区、产品和应用细分研究报告
- 高德地图是直线距离吗_是直线直线
- 2021011206贾天乐实验五
- 带随机种子的javascript随机函数
- Visual Studio 2019 性能探查器使用
- Unable to find a version of the runtime to run this application解决方法
热门文章
- python读取文件多行内容-使用python读取.text文件特定行的数据方法
- python爬虫从入门到精通-Python爬虫从入门到精通视频(2018新版)
- python类型-python语言中的数据类型有哪些
- mapreduce编程实例python-Python模拟MapReduce的流程
- python源代码不需要编译成什么-python程序不需要编译吗
- python中可以用中文作为变量-在python字典中使用变量作为键名
- python快速入门答案-总算懂得python脚本快速入门教程
- python错误-Python错误和异常(error)处理技巧
- python语法教程-Python语言的核心语法(1)(语法教程)(参考资料)
- python散点图拟合曲线-Python解决最小二乘法拟合并绘制散点图