同步和异步
在开发中,我们会经常听到同步和异步。我们可以这样子理解,同步,就像是一个队列在排队,一个个去执行;异步没有队列,大家都在同时执行(微观上这是不可能的), 我们看到的异步就是多个操作在不停的快速切换运行,快到我们感觉不出来。异步就是在执行一个函数的时候还能执行另一个函数。
同步
这个比较简单,就是正常的代码执行流程:
console.log("同步任务1");
console.log("同步任务2");
异步
异步任务可以更改同步任务的执行顺序。
setTimeout(()=>{
console.log("同步任务1");
},0);
console.log("同步任务2");
这里的输出顺序和以上的输出顺序是不一样的。这里的setTimeout,是一个js中的定时器,但是,我们这里后面的定时时间是一个0,不等待,这就是js异步的基本实现用法;这里要说到线程相关的,js是单线程的,不像其他的java是有多线程的概念,单线程的同步任务就要按顺序执行,而这里js实现的异步,就是一个异步栈的概念,把所有的同步任务放到同步栈里执行,同步栈里的任务执行完毕后就会切换到去执行异步栈的任务(函数)。
虽然用setTimeout可以实现异步,但是,我们一般不会这样子做,js为我们提供了异步实现的另外两种方式:
promise实现异步:
new Promise((resolve,reject)=>{
resolve("我是异步任务里的输出");
}).then(msg=>{
console.log(msg);
})
console.log("同步任务2");
注:js提供的Promise让我们可以方便的实现异步的写法,里面的resolve调用后,会走到Promise后面的then里面的函数里;而reject调用后会执行到promise后的catch方法里,例如 :
new Promise((resolve,reject)=>{
reject("我是异步任务里的输出");
}).then(msg=>{
console.log(msg);
}).catch(msg=>{
console.log("我是reject:"+msg);
})
console.log("同步任务2");
注:我们在实际开发工作中,都会在Promise的函数里向后台发送请求,并请求成功后调用resolve,执行到then后面的函数里,如果请求出错,则执行reject执行到后面的catch里。
async…await实现异步:
虽然我们可以使用promise来实现异步请求,但是,如果这样子写后面添加then不太好理解,所以, 后来js提供了 同步写法实现异步的方法 ,这就是我们现在用的async…await
function reqeustTest(){
return new Promise((res,rej)=>{
setTimeout(()=>{
res("我是向后台请求的值");
},2000);
})
}
async function asyncFun(){
let res = await reqeustTest();
console.log(res);
// 以下是老的写法,使用then
// reqeustTest().then(res=>{
// console.log(res);
// })
}
asyncFun();
console.log("同步任务2");
注:
看以上的写法,我们在asyncFun的方法定义的前面加了async关键字,里面的requestTest前面加了await,从字现意思我们知道是等待的意思。
下面还有老的写法,是使用的then定法,我们可以看到await的同步写法和我们平常的编程习惯更接近。
拓展:
异步任务里还有细分,宏任务和微任务,大家如果感兴趣可以去网上搜下资料,我们使用的setTimeout属于异步任务里的宏任务,而promis是异步任务里的微任务!