发布时间:2023-09-19 14:00
什么是异步呢,很好理解,一般的我们的代码执行的顺序是同步的,也就是执行完这条代码再执行下一条代码,而异步就是我们在某个时间点执行某个代码,而不是顺序执行
创建一条我们比较熟的预加载,这里就是一个典型的异步操作
var set=new Set();
for(var i=2;i<5;i++){
var img=new Image();
img.src=\"./img/\"+i+\"-.jpg\";
img.addEventListener(\"load\",loadHandler);
}
function loadHandler(e){
set.add(this);
if(set.size===3){
console.log(\"全部加载完成\")
}
}
还有一些比较常见的封装好的函数,也是异步擦欧洲哦
setTimeout();
setInterval();
requestAnimationFrame();
console.log(\"a\");
for(var j=0;j<1000000000;j++){
}
console.log(\"b\");
一般程序员的思维就是不产生异步代码,让代码按顺序执行下去,于是就会出现在一个函数中不断回调我们所需要的代码,这样就会产生回调地狱,回调地狱会让代码一直往下沉,永远跳不除这个地狱中。
典型的回调地狱,因为我想让图片1加载完再加载图片2,然后图片3,4,5,所以就会不断回调onload事件,这样就会越陷越深,(用函数式编程就会完美地解决这个问题。)
var img=new Image();
img.src=\"./img/2-.jpg\";
img.onload=function(){
var img1=new Image();
img1.src=\"./img/3-.jpg\";
img1.onload=function(){
var img2=new Image();
img2.src=\"./img/4-.jpg\";
img2.onload=function(){
console.log(\"a\");
}
}
}
promise的出现完美地解决了这个问题,我们即使不用函数式编程也可以让代码异步执行,而不是顺序执行
Promise语法
var p= new Promise(function(resolve,reject){
resolve();
})
p.then(function(){
console.log(\"aaa\");
})
var p= new Promise(function(resolve,reject){
reject();
});
p.catch(function(){
console.log(\"bbb\");
})
promise分别有两个参数resolve,reject
这两个参数又分别可以传入一个参数。(仅一个参数)
当执行reject时,会执行后面的then当中第二个函数,如果有catch()
则会执行catch方法中的函
如果既有then中第二个函数也有catch,则完成then中第二个函数,catch不执行
注意!这两个参数只能选一个执行。
注意!!!
var p= new Promise(function(resolve,reject){
reject();
resolve();
console.log(\"ccc\");
// 这两个方法只能二选其一执行
});
p.then(function(){
console.log(\"aaa\");
}).catch(function(){
console.log(\"bbb\");
})
console.log(p);
第二种写法,静态写法
这种写法跟上面的构建函数的写法完全相同,执行的功能也完全相同。
Promise.resolve().then(function(){
})
链式结构
在promise的写法中,then是可以连着写的,也就是我创建的then或者catch可以进行下一层
链式结构
loadImage(\"./img/2-.jpg\").then(function(){
console.log(\"加载完成2-jpg\");
return loadImage(\"./img/3-.jpg\");
}).then(function(){
console.log(\"加载完成3-jpg\");
return loadImage(\"./img/4-.jpg\");
}).then(function(){
console.log(\"加载完成4-jpg\");
});
promise的状态
PromiseState=pending 初始值
当执行resolve函数时或者reject函数时,首先判断PromiseState是不是pending,
如果是pending, 则运行掉用then中函数或者catch的函数
如果不是pending,就不执行后面的函数
如果执行resolve后就会被标记为fulfilled
如果执行reject后就会被标记为rejected
fulfilled resolve执行状态
rejected reject执行状态
pending 起始状态,挂起状态
promise的不同的三种状态,可以对应不同 的方法
小练习:用promise完成一个简单的红绿灯案例
function showLight(light,time){
if(!time) time=2000;
return new Promise(function(resolve,reject){
setTimeout(function(){
console.log(light)
resolve();
},time);
})
}
fns();
function fns(){
showLight(\"红灯\").then(function(){
return showLight(\"黄灯\");
}).then(function(){
return showLight(\"绿灯\");
}).then(function(){
fns();
})
}
async 和await
async 返回一个Promise对象
await 后面只能等待promise对象resolve或者reject,其他都不行
await必须写在async函数中
async中的return 等同这个Promise的resolve
async中throw等同于这个Promise的reject
但是不管是return或者throw都不可异步返回,只有在使用await后才可以异步返回
async function fns(){
return 1;//使用return 相当于执行了resolve
throw \"aaa\";//使用 throw相对于执行了reject
一个小案例就能更好的理解这两个类promise
这里我需要按照a两秒后执行b,三秒后执行c,所以需要用到await
async function fns(){
console.log(\"a\");
await waitTime(2000);//阻塞式同步
console.log(\"b\");
await waitTime(3000);
console.log(\"c\");
}
function waitTime(time){
return new Promise(function(resovle){
setTimeout(function(){
console.log(time/1000+\"秒执行完成\");
resovle();
},time);
})
}
同步任务 和 异步任务
这里的任务指的就是事件
异步任务分为两种:微任务和宏任务
宏任务 setTimeout setInterval
微任务 Promise
先执行同步任务,遇到微任务时,将其放在当前任务列的最底端,
遇到宏任务则会开辟一个新任务列,并且放在任务列的最顶端
这里我们需要清楚任务的执行顺序和创建顺序,先缕清执行顺序,然后在理解创建顺序,这里经常出现面试题