引入
需求:编写一个 delay 延迟函数,执行 delay 函数,可以把我们要做的事情延迟一段时间执行
解决方案:基于“回调函数”的方式来管理
const delay = function delay(interval, callback) {// 处理参数if (typeof interval === 'function') {callback = intervalinterval = 1000}if (typeof callback !== 'function') throw new TypeError('callback is not a function')interval = +intervalif (isNaN(interval)) interval = 1000// 设置定时器,把callback延迟执行setTimeout(() => {callback()}, interval)}
并行操作
先后(类似于同时)设置三个定时器,谁先到先执行谁 特点:三件事之间没有任何的关联/依赖
delay(3000, () => {console.log('A')})delay(() => {console.log('B')})delay(2000, () => {console.log('C')})
—->’B’/‘C’/‘A’ 三件事都执行完毕需要 3000ms
特殊情况:都处理完毕后,做统一的一些事情
const complete = function complete() {console.log('并行操作都处理完毕了')}let n = 0, num = 3delay(3000, () => {console.log('A')n++if (n >= num) complete()})delay(() => {console.log('B')n++if (n >= num) complete()})delay(2000, () => {console.log('C')n++if (n >= num) complete()})
串行操作
如果三件事有关联,例如:必须先处理A,A处理的结果会作为B处理的条件…也就是执行的顺序必须是 A->B->C 串行操作:必须在上一个处理完毕后,才能设置下一个定时器,因为三个的执行是有关联和依赖的
delay(3000, () => {console.log('A')delay(() => {console.log('B')delay(2000, () => {console.log('C')})})})
“回调地狱”
- 基于回调函数的方式来管理异步操作,在“并行”操作中没啥太大的问题,但是在“串行”操作中,会引发“在回调函数中,嵌套回调函数…”,这就是回调地狱!!
在真实的工作中,我们用到的ajax请求“全部都是异步操作(虽然它支持同步的处理)”
JQ:$.ajax 基于回调函数的方式,来管理ajax异步请求的$.ajax({url:'',method:'GET',data:{// 传参信息},dataType:'json', //把从服务器获取的数据,转换为对象...,success(result){// 请求成功的回调函数「result:从服务器获取的数据信息」},...})
Ajax并行
同时发送多个异步请求,谁先从服务器获取数据,就先处理谁
特殊情况:都处理完毕后,做统一的一些事情
Ajax串行
多个请求之间有依赖,需要依次发送「上一个请求结束,才能发送下一个请求」
$.ajax({url: '/api/info',success(result) {// 第一个请求成功// ...$.ajax({url: '/api/ranking?id=' + result.id,success(result2) {// 第二个请求成功// ...$.ajax({url: '/api/prize?rank=' + result2.rank,success(result3) {// 第三个请求成功// ...}})}})}})
基于 Promise 管理异步操作
const delay = function delay(interval = 1000) {return new Promise(resolve => {setTimeout(() => {resolve()}, interval)})}
Promise并行:
无需自己写计数器监测是否都成功,基于 Promise.all 就解决了
let p1 = delay(3000).then(() => {console.log('A')})let p2 = delay().then(() => {console.log('B')})let p3 = delay(2000).then(() => {console.log('C')})Promise.all([p1, p2, p3]).then(() => {console.log('并行操作都处理完毕了')})
Promise串行:
有效避免回调地狱 ```javascript delay(3000) .then(() => { console.log(‘A’) return delay() }) .then(() => { console.log(‘B’) return delay(2000) }) .then(() => { console.log(‘C’) })
;(async function(){ await delay(3000) console.log(‘A’)
await delay() console.log(‘B’)
await delay(2000) console.log(‘C’) })()
<a name="Trey5"></a>### 简单了解axios> 平时项目中,我们可以使用 axios 插件来发送数据请求,相比较于 $.ajax,其不是基于 callback 回调函数的方式管理异步请求的,而是基于 Promise 来管理异步操作的!!> 需求:在项目中,有三个接口请求(串行请求),现在需要我们分别调用三个接口,完成数据的获取和绑定<br /> 接口1:/api/info -> {id:xxx,....}<br /> 接口2:/api/ranking?id=xxx -> {rank:27}<br /> 接口3:/api/prize?rank=27<a name="urSvF"></a>#### 串行```javascriptaxios.get('/api/info').then(result => {// 第一个请求成功 ...return axios.get(`/api/ranking?id=${result.id}`)}).then(result2 => {// 第二个请求成功 ...return axios.get(`/api/prize?rank=${result2.rank}`)}).then(result3 => {// 第三个请求成功 ...})
配合async await使用
(async () => {let result = await axios.get('/api/info')// 第一个请求成功 ...result = await axios.get(`/api/ranking?id=${result.id}`)// 第二个请求成功 ...result = await axios.get(`/api/prize?rank=${result.rank}`)// 第三个请求成功 ...})()
并行
axios.get('/api/list').then(() => {// ...})axios.get('/api/info').then(() => {// ...})axios.get('/api/test').then(() => {// ...})
