AJAX进阶

链式调用

同步代码和异步代码

同步代码:逐行执行,需原地等待结果后,才继续向下执行.

异步代码:调用后耗时不阻塞代码继续执行(不必原地等待),在将来完成后触发回调函数传递结果

常见异步代码:

  • 定时器:setTimeout / setInterval
  • 事件(点击事件······)
  • AJAX

回调函数地狱

概念:在回调函数中嵌套回调函数,一直嵌套下去就形成了回调函数地狱

在异步代码中,因为会通过回调函数来传递结果,所有可能会造成回调函数地狱

 Promise 链式调用

Promise 对象在进行 .then() 方法后,会返回一个全新的Promise 对象

另外,可以使用return来设置返回的Promise 对象

可以利用这个新Promise 对象,来跳出回调函数地狱

const p = new Promise((resolve, reject) => {
    resolve('ok')
})

//调用情况1
p.then(result => {
    console.log(result)
    return new Promise((resolve, reject) => {
        resolve('ok')
    })
}).then(result => {
    console.log(result)
})

//调用情况2
const p2 = p.then(result => {
    console.log(result)
    return new Promise((resolve, reject) => {
        resolve('ok')
    })
})

p2.then(result => {
    console.log(result);
})

 axios 链式调用

axios本质是permise对象,也可以使用链式调用

// 1. 得到-获取省份Promise对象
let pname = ''
axios({ url: 'http://hmajax.itheima.net/api/province' }).then(result => {
    pname = result.data.list[0]
    // 2. 得到-获取城市Promise对象
    return axios({ url: 'http://hmajax.itheima.net/api/city', params: { pname } })
}).then(result => {
    const cname = result.data.list[0]
    // 3. 得到-获取地区Promise对象
    return axios({ url: 'http://hmajax.itheima.net/api/area', params: { pname, cname } })
}).then(result => {
    console.log(result)
    const areaName = result.data.list[0]
    console.log(areaName);
})

async 函数和 await关键字

async 函数和 await关键字可以简化通过Promise 对象所写的异步代码

原理:在 async 函数内,使用 await 关键字可以取代 then 函数,等待获取 Promise 对象成功状态的结果值

// 1. 定义async修饰函数
async function getData() {
  // 2. await等待Promise对象成功的结果
  const pObj = await axios({url: 'http://hmajax.itheima.net/api/province'})
  const pname = pObj.data.list[0]
  const cObj = await axios({url: 'http://hmajax.itheima.net/api/city', params: { pname }})
  const cname = cObj.data.list[0]
  const aObj = await axios({url: 'http://hmajax.itheima.net/api/area', params: { pname, cname }})
  const areaName = aObj.data.list[0]

事件循环

概念

事件循环是JS运行代码顺序的机制,是执行代码和收集异步任务的模型

执行机制:

  1. 首先自上而下在调用栈中执行同步代码
  2. 遇到异步代码,则将异步代码交给宿主浏览器环境执行
  3. 异步代码有结果后,回调函数放入任务队列
  4. 调用栈空闲后(同步代码全部执行完)调用任务队列中的回调函数

例: 以下输出结果为 1 5 3 2 4

/**
 * 目标:阅读并回答执行的顺序结果
*/
console.log(1)
setTimeout(() => {
  console.log(2)
}, 0)
function myFn() {
  console.log(3)
}
function ajaxFn() {
  const xhr = new XMLHttpRequest()
  xhr.open('GET', 'http://hmajax.itheima.net/api/province')
  xhr.addEventListener('loadend', () => {
    console.log(4)
  })
  xhr.send()
}
for (let i = 0; i < 1; i++) {
  console.log(5)
}
ajaxFn()
document.addEventListener('click', () => {
  console.log(6)
})
myFn()

宏任务与微任务

异步任务分为宏任务与微任务

  • 宏任务:由浏览器环境执行的异步代码
  • 微任务:由 JS 引擎环境执行的异步代码

执行时优先微任务 

 Promise.all 静态方法

用于合并多个 Promise 对象,等待所有同时成功完成(或某一个失败),做后续逻辑

    // 1. 请求城市天气,得到Promise对象
    const bjPromise = axios({ url: 'http://hmajax.itheima.net/api/weather', params: { city: '110100' } })
    const shPromise = axios({ url: 'http://hmajax.itheima.net/api/weather', params: { city: '310100' } })
    const gzPromise = axios({ url: 'http://hmajax.itheima.net/api/weather', params: { city: '440100' } })
    const szPromise = axios({ url: 'http://hmajax.itheima.net/api/weather', params: { city: '440300' } })

    // 2. 使用Promise.all,合并多个Promise对象
    const p = Promise.all([bjPromise, shPromise, gzPromise, szPromise])
    p.then(result => {
      // 注意:结果数组顺序和合并时顺序是一致
      console.log(result)
      const htmlStr = result.map(item => {
        return `<li>${item.data.data.area} --- ${item.data.data.weather}</li>`
      }).join('')
      document.querySelector('.my-ul').innerHTML = htmlStr
    }).catch(error => {
      console.dir(error)
    })

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值