ajax回调函数_简单理解JavaScript异步回调与Promise

v2-5873a29dd95231089aee65f2f53b335c_1440w.jpg?source=172ae18b

往往异步与同步的概念我们模模糊不清

那什么是异步?什么是同步呢?

异步:如果不能直接拿到结果,就是异步。

举例:如果你在餐厅门口等座位,你拿到号可以去逛街。什么时候真正吃饭呢?

你可以每隔10分钟去问一下(轮询)你也可以扫码用微信直接收通知(回调)

以AJAX为例:request.send()之后,并不能直接得到response,console.log(request.respone)试试,必须等到 readyState变为4后,浏览器回头调用request.onreadyStatechage函数,我们才能得到request.response,这和餐厅给你发微信提醒的过程是类似的。

同步:如果能直接拿到结果,就是同步

举例:比如你在医院挂号,你拿到号才离开窗口,同步任务可能消耗10毫秒,也可能消耗3秒,总之,不拿到结果你是不会离开的。

回调(callback):写了却不调用,给别人调用的函数就是回调。

你写给自己用的函数不是回调,你写给别人用的函数是回调。

举例:把函数1给函数2 f1是回调

function f1(){}
function f2(fn){
fn()
}
f2(f1)

分析:

1.我调用f1没有?答:没有调用

2.我把f1传给f2了没有?答: 传了

3.f2调用f1没有?答:调用了

4.那f1是不是我写给f2调用的函数?答:是所以f1是回调

function f1(x){
console.log(x)
}
function f2(fn){
fn('你好’)
}
f2(f1)
  • f1怎么会有一个x参数

fn('你好')中的fn就是f1;

fn('你好')中的你好会被赋值给参数x,所以x就是'你好',x可以改成任意其他名字,x表示第一个参数而已

异步和回调的关系

关联

异步任务需要在得到结果时通知JS来拿结果

怎么通知呢?

可以让JS留一个函数地址给浏览器,异步任务完成时,浏览器调用该函数地址即可。同时把结果作为参数传给该函数(电话里通知你可以来吃饭了),这个函数是我写给浏览器调用的,所以是回调函数。

区别

异步任务需要用到回调函数来通知结果,但回调函数不一定只能用在异步任务里。回调可以用到同步任务里array.forEach(n=>console,log(n))就是同步回调

异步为什么会用到回调?

它为了拿到那个不能拿到的结果,必须使用回调。

判断同步异步:

1如果一个函数的返回值处于

  • setTimeout
  • AJAX(即XMLHttpRequest)
  • AddEventListener

这三个东西内部,那么这个函数就是异步函数

AJAX设置为同步,会让请求期间页面卡住,不建议这样做。

2.判断同步异步举例

function  摇骰子(){
setTimeout(()=>{
return parseInt(Math,radom()*6)+1},1000)
return undefined
}

分析:

摇骰子()没有写return,那就是return undefined,箭头函数里有return返回真正的结果,所以这是一个异步函数/异步任务。

return属于不同的函数。

摇骰子续

const n= 摇骰子()

console.log(n)//undefined

怎么才能拿到异步结果?

可以用回调,写个函数,然后把函数地址给它

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

简化箭头函数:

由于f1声明之后只用了一次,所以可以删掉f1

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

改为

摇骰子(x=>{console.log(x)})

再简化

摇骰子(console.log)

注意:如果参数个数不一致就不能这样简化

回调错误简化案例

const array =['1','2','3'].map(parseInt)

console.log(array)

结果:[1,NaN,NaN]

分析:

直接传给parseint相当与

//parseInt(‘1’,0,arr)=>1

//parseInt(‘2',1,arr)=>NaN

把2当作二进制解析,二进制没有2,就得到NaN,同理3也得到NaN

本来形式

const array=['1','2','3'].map((item,i,arr)=>{

return parseInt(item)

})

console.log(array)

结果:[1,2,3]o

异步任务不能拿到结果,于是我们传一个回调给异步任务,异步任务完成时调用回调,调用的时候把结果作为参数

思考:如果异步任务有两个结果成功或失败,怎么办?

方法一:回调接受两个参数

方法二:搞两个回调

但是回调时异步回调时存在问题的,容易出现回调地狱

Node中有大量的异步 IO 操作,被封装成基于回调的函数,遇到复杂的业务逻辑很容易形成多级缩进的代码,在左侧形成一个由空格(或 Tab)组成的三角形,代码变得非常难读,被称为回调地狱。

v2-7732a1a54a35841035580cdbdbb17ac5_b.jpg

回调有什么不足?

  • 命名不规范
  • 容易出现回调地狱,代码变得看不懂
  • 很难进行错误处理

怎么解决上述三不足呢?

因此就有了Promise

Promise 是目前前端解决异步问题的统一方案

promise是什么?

是1976年发明的一种设计模式(写的好的代码,取个名字就叫设计模式)

写法:

只需要在函数里直接return;
return new Promise((resolve,reject)=>{})
//任务成功的时候调用 resolve,失败的时候调用 reject
//注意resolve和reject也是函数且只接收一个参数
//resolve 和 reject 可以改成任何其他名字,不影响使用,但一般就叫这两个名字

Promise 介绍:

  • 1976年,Danlel P.Fredman和David lai两人提出Promise思想,后人基于此发明了Future,Delay,Defeered等
    • Promise 不是前端发明的,前端结合了Promise和JS制定了Promise/A+规范,该规范详细描述了Promise的原理和使用方法
  • window.Promise 是一个全局函数,可以用来构造 Promise 对象

如何使用Promise?

第一步

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

任务成功则调用resolve(result);任务失败则调用reject(error),resolve和reject会再去调用成功和失败函数

第二步

使用.then(Success,fail)传入成功和失败函数

使用 return new Promise((resolve, reject)=> {}) 就可以构造一个 Promise 对象,构造出来的 Promise 对象含有一个 .then() 函数属性

resolve 和 reject 并不是 .then(succes, fail)里面的 success 和 fail,resolve 会去调用 success,reject 会去调用 fail,虽然也是回调,但不需要记success和fail了,then的第一个参数就是success,then的第二个参数就是fail

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值