异步&回调
如果能直接拿到结果,那就是同步
比如在医院挂号,你要拿到号你才会离开窗口。同步任务可能消耗几毫秒到几十毫秒不等,总之不拿到结果你是不会离开的。
如果不能会直接拿到结果,那就是异步
比如你在餐厅门口等位,你拿到号之后可以先去逛一下,然后没过十几分钟回去问一下能不能吃饭了(轮询),你也可以通过微信接收叫号通知(回调)
来给异步举个栗子!
以AJAX为例
request.send()之后。并不能直接得到response,。必须等到readyState变成为4后,浏览器才回头调用request.onreadystatechange函数,我们才能得到request.response。这就是餐厅通过微信叫号给我们发通知信息一样的。
回调 callback
浏览器回头调用这就是回调。你写给自己用的函数不是回调,你写给别人的函数,就是回调。假设request.onreadystatechange就是写给浏览器调用的,意思就是浏览器回头调用一下这个函数。写了 却不调用,给别人调用的函数,就是回调。
回调代码举例
把函数1给另一个函数2
function f1(){}
function f2(fn){
fn()
}
f2(f1)
上面代码定义了两个函数,分别是f1和f2,这个时候调用了f2(注意!f2不是回调,因为是我自己调用的f2),在调用f2的时候传了一个f1的函数,这个f1就是回调。
因为我没有调用f1,我把f1传给了f2,f2调用了f1,所以f1是我写给f2调用的函数,f1是回调。
f1怎么会有一个x参数
function f1(x){
console.log(x)
}
function f2(fn){
fn('你好')
}
f2(f1)
fn('你好')中fn就是f1,fn('你好')中的 '你好' 会被赋值给参数x,所以x就是 ' 你好 ' !x可以改成任意其他的名字,x表示第一个参数而已。
异步和回调的关系
关联
异步任务需要在得到结果时通知JS来拿结果。
JS可以留一个函数地址给浏览器,方便浏览器进行通知。
异步任务完成时浏览器调用该函数地址即可。
同时吧结果作为参数传给该函数。
这个函数是我写给浏览器调用的,所以是回调函数。
注意!我们发送通知的时候不一定要用到异步,还可以用到轮询,每隔一定时间去询问一下。异步常常会用到回调,但不一定要用到回调。
区别
异步任务需要用到回调函数来通知结果(也饿可以用到轮询)。
但是回调函数不一定只用在异步任务里面,回调可以用到同步任务里array.forEach(n=>console.log(n))就是同步回调。
判断同步异步
如果一个函数的返回值处于以下情况
setTimeout
AJAX(即XMLHttpRequest)
AddEventListener
在这三个东西内部,那么这个函数就是异步函数
注意!不要将AJAX设置为同步的,因为将AJAC设置为同步,这样做会使请求期间页面卡住。
老规矩举个栗子
让我们开始来摇骰子
function 摇骰子(){
setTimeout(()=》{
return parseInt(Math.random() * 6) + 1
},1000)
}
分析:
首先摇塞子()没有写return,也就是说摇塞子返回出来的是undefined。但是在摇骰子里面有一个箭头函数,箭头函数返回了真正的结果。
所以这是一个异步函数或者叫做异步任务
给我继续摇塞子!!!
如果我们在后面加上这么两句
const n = 摇塞子()
console.log(n)
由于现在我们拿到n返回回来的是“undefined”,所以那么我们需要拿到异步的结果的话,就得用回调,写个函数然后把函数的地址给它。
function f1(x){console.log(x)}
摇塞子(f1)
然后要求摇骰子函数得到结果后把结果作为参数传给f1
function 摇塞子(fn){
setTimeout(()=>{
fn(parseTnt(Math.random()*6)+1)
],1000)
}
简化函数
由于f1声明之后只用的一次所以可以删掉
function f1(x){ console.log(x)}
摇塞子(f1)
//该为
摇塞子(x => {
console.log(x)
})
//再简化为
摇塞子(console.log)
异步和回调总结!
异步任务不能拿到结果,于是我们传一个回调给异步任务。
异步任务完成时候调用回调。
调用的时候。
Promise
Promise 对象用于表示一个异步操作的最终完成 (或失败), 及其结果值.
创建方法
new Promise(function(resolve,reject){....})
任务成功则调用resolve(result)
任务失败则调用reject(error)
resolve和reject 会在去调用成功和失败的函数。
使用.then(success,fail)传入成功和失败函数
基本用法
Promise可以用于定义一个什么是成功了,什么是失败了。
new Promise(function (resolve,reject) {
console.log('promise准备阶段');
resolve("成功!");
reject("失败!");
})
输出结果:Promise准备阶段。
Promise一共有三个状态“准备状态、成功状态、失败状态”,上面代码当中Promise是刚刚定,所以是进入准备状态,因为每new一个Promise都会进入准备状态,我们还没有运行就进入准备状态了,所以我们经常通过一个函数给它包裹起来。
function asyncPro(){
return new Promise(function (resolve,reject) {
console.log('promise准备阶段');
resolve("成功!");
reject("失败!");
});
}
asyncPro();
输出结果:
Promise准备阶段
成功!
Promise.all()
MDN介绍:返回一个 Promise 实例,此实例在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败 promise 的结果。
如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h63369.shtml