47-【前后分离】异步与Promise

异步、同步
  • 同步:可以直接拿到结果 比如医院挂号

  • 异步:不能直接拿到结果 比如:网红餐厅 两种方式:自己问(轮询) 微信提醒(回调)

其实AJAX的请求与响应就是异步,send()后无法打出console.log(request.response)

js提供onreadystatechange()构造函数,只有当request.readystate值为4时,浏览器才回调这个函数,这个函数是js提供给浏览器用的,

request.send()
console.log(request.response)
setTimeout(()=>{console.log(request.response)},2000)

无结果 
h1 {
    color: blue;
}
回调 callback 写给别人用的函数
function f1(){console.log('hi')}
function f2(fn){fn()}
f2(f1)

hi
  • 我没有调用f1
  • f2调用了f1
  • f1传给了f2

f1是回调函数,f2是我自己调用的

  • 为什么f2一定会调用f1?

f1创建出来就是让调用的,f2接受fn 参数,而f2必定会调用f1

  • 为什么f1为什么是回调函数,不是字符串啥的?

字符串会报错,不可能不是函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tdO1OtC8-1591167979904)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200510212331167.png)]

异步与回调的关系

联系:异步是得到结果时再通知js,js留函数地址给浏览器,异步任务完成,浏览器调用函数地址,同时把结果作为参数传给该函数,这个函数就我写给浏览器调用的,叫调用函数

区别:异步任务可以用回调函数来通知结果,当然也有轮询

​ 回调函数不只是可以用于异步,还可用于同步回调forEach((item)=>console.log(item))

异步函数 函数返回值处于三个内部
  • AJAX(XMLHttpRequest)
  • setTimeout
  • addEventListener

AJAX不要设置同步( request.open(‘GET’, ‘2.js’,false)),这样只能一个执行完再执行另外一个,造成无法操作

异步函数 摇骰子案例
function 摇骰子(){
    setTimeout(()=>{
        return parseInt(Math.random()*6+1) //1-6的随机数
    },2000)
}

摇骰子()
undefined

此时摇骰子()没有return,调用返回undefined;setTimeout()有函数值,有return

如何拿到异步函数的值?引入回调函数
function f1(x){console.log(x)} //回调函数 把异步完成的结果作为参数
摇骰子(f1)  //把函数地址给他

两步变化

function 摇骰子(fn){
setTimeout(()=>{
fn( parseInt(Math.random()*6+1))
},2000)
}

搞定 可以拿到异步任务值了

摇骰子(f1)
1
摇骰子(f1)
3
回调函数简化代码

x=>console.log(x)

console.log

function f1(x){console.log(x)} 
摇骰子(f1) 

摇骰子(x=>console.log(x))
undefined
VM1465:1 4
摇骰子(console.log)
undefined
VM1407:3 3
简化中的坑 参数必须一致

[‘1’,‘2’,‘3’].map((item)=>{return parseInt(item)})

['1','2','3'].map(parseInt)
(3) [1, NaN, NaN]
['1','2','3'].map((item,index,arr)=>{return parseInt(item,index,arr)})
(3) [1, NaN, NaN]

//正确格式
['1','2','3'].map((item,index,arr)=>{return parseInt(item)})
(3) [1, 2, 3]
['1','2','3'].map((item)=>{return parseInt(item)})
(3) [1, 2, 3]

由于map有三个参数 不能直接最简化,最简化无法三对 1

总结-异步1个结果
  • 异步任务不能拿到结果
  • 传回调给异步任务
  • 异步任务完成进行调用回调
  • 调用时结果作为参数来回调
Promise的用法 处理两个结果

takGnI.png

存在三种问题
  • 回调地狱
  • 回调名称不规范,顺序不规范。成功与失败时,用success+error,success+fail,done+fail
  • 很难进行错误处理
析构赋值
const{success,fail}=options
//展开代码为
const success=options.success
const fail=options.fail
封装AJAX
//封装AJAX
ajax = (method, url, options) => {
    const {
        success,
        fail
    } = options
    const request = new XMLHttpRequest()
    request.open(method, url)
    request.onreadystatechange = () => {
        if (request.readyState === 4) {
            if (request.status < 400) {
                success.call(null, request.response)
            } else {
                fail.call(null, request.request.status)
            }
        }
    }
    request.send()
}
//对封装好的AJAX调用
ajax('get', '/xxx', {
    success(response) {},
    fail: (request, status) => {}
})

两种函数缩写

success(response){} //有this
fail:(request,status)=>{} //无this
用Promise来调用AJAX

1.修改ajax源码,加return new Promise((resolve,reject)=>{...})

任务成功调用 resolve(result)

任务失败调用 reject(error)

resolve和reject会调用成功和失败函数

//封装AJAX
ajax = (method, url, options) => {
  return new Promise((resolve,reject)=>{
    const {
        success,
        fail
    } = options
    const request = new XMLHttpRequest()
    request.open(method, url)
    request.onreadystatechange = () => {
        if (request.readyState === 4) {
            if (request.status < 400) {
                resolve.call(null, request.response)
            } else {
                reject.call(null, request.request.status)
            }
        }
    }
    request.send()
   })
}

2.promise调用AJAX

ajax('get','/xxx').then((response)=>{},(request)=>{})

ajax返回的是.then方法的对象

封装的ajax的缺点
  • post无法上传数据
  • 不能设置请求头 request.setRequestHeader(key,value)

怎么解决:

  • 用jQuery.ajax:JQuery中文文档=》jQuery.ajax看参数,实例
axios 目前最新的库

axios 作弊表

axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
  • JSON自动处理,把content-Type为JSON的转为对象,自动调用JSON.Parse
  • 请求和响应拦截器
  • 生成不同实例
总结

1.异步是什么?

不能直接拿到请求

2.异步为什么用回调?

为了拿到这个结果

3.回调存在的三个问题?

  • 回调地狱
  • 成功或者失败的命名和顺序问题:successuccess+error,success+fail,done+fail
  • 很难进行错误处理

4.Promise是1976年提出的一种设计模式

5.如何用Promise?

return new Promise((resolve,reject)=>{})

6.axios怎么用?

https://www.bootcdn.cn/ 里axios

 <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.min.js"></script>
  <script>
    axios.get('/xxx')
//成功时返回
  .then(function (response) {
    console.log(response);
  })
//失败时返回
  .catch(function (error) {
    console.log(error);
  });
  </script>

7.Promise是前端解决异步的统一方案

tatuLt.png
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值