事件循环
https://www.bilibili.com/video/BV1kf4y1U7Ln?from=search&seid=7029327095728723738
同步与异步:都是在一条流水线上运作,没有一边一边(多线程)的说法,同步和异步的差别就在于这条流水线上各个流程的执行顺序不同。
异步操作:是指可以改变正常执行顺序的操作
浏览器由很多模块组成,有解析html和css的模块,有解析js的模块,有定时器模块,有ajax模块。
其中v8引擎就是用来解析js的,js是单线程是因为v8引擎是单线程,当v8引擎解析到异步代码时,比如定时器,就会把异步代码交给相关的模块处理,处理完之后,再交给事件队列中排队,当执行栈有空时,消息队列就把事件交给调用栈执行。
拿定时器来说,当v8引擎从上往下执行代码,读到定时器的时候。就会把定时器交给定时器模块处理,然后v8引擎继续执行代码,定时器模块会计时,当时间到了,就会把任务交给事件队列,当执行栈有空闲时,消息队列就会把任务推给执行栈,执行栈执行完毕之后将其弹出
浏览器是多进程的(定时器进程、JS引擎等等),JS引擎中,可以分为同步和异步任务,其中:
1)同步任务全部通过主线程执行,形成 执行栈(函数调用形成了一个栈帧,子函数被一个一个加加进去)
2)异步任务通过事件触发线程或者定时器线程处理,形成 任务队列,异步又分macrotask(setInterval()
setTimeout()
) 和 microtask(Promise的then/catch、Async\Await),先微后宏
3)当执行栈中的任务全部处理完成,主线程为空闲的时候,会从任务队列中提取任务到执行栈中执行。
1.Promise
promise (就是能把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数)
里面可以有同步操作也可以有异步操作
new Promise((resolve, reject) => {
$.ajax({
url: "https://easymock.com/mock/5c249dbe46e8386d0b21b475/example_copy_copy/promisetest",
success: res => {
if (res.code == 0) {
resolve(res.data)
} else {
reject(res.desc)
}
}
});
})
.then(res => {
console.log(res);
},err =>{
console.log(err)
})
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('执行完成');
resolve('随便什么数据');
}, 2000);
});
//注意!我只是new了一个对象,并没有调用它,我们传进去的函数就已经执行了,这是需要注意的一个细节
如果调用resolve函数和reject函数时带有参数,那么它们的参数会被传递给回调函数
Promise.resolve方法允许在调用的时候不带任何参数,直接返回一个状态为resolved的Promise对象
Promise.rejecet会原封不动的将reject的理由变成后续方法的参数
(reject的作用就是把Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调)
then():用来对resolve()回调,catch()对reject()的回调,或者发生错误时进入
Promise.all()会把所有异步操作的结果放进一个数组中传给then
Promise.all 异步并不是按顺序执行—Promise.all等待所有Promise执行完毕之后,按照放在all中的先后顺序将resolve()返回的数据放在Promise.all的resolve中——想要顺序的话就用for(…)
Promise
.all([runAsync1(), runAsync2(), runAsync3()]) //并行处理异步操作
.then(function(results){
console.log(results);
});
Promise.race()用race给某个异步请求设置超时时间https://blog.csdn.net/hyupeng1006/article/details/80351174
2.async/await
async 声明的函数 会返回一个Promise对象 并且状态为resolve(如果在函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象), 那么它的执行顺序跟Promise对象的执行顺序是一样的
await 关键字只能放到async 函数里面, 正常情况下,await 命令后面跟着的是 Promise ,如果不是的话,也会被转换成一个 立即 resolve 的 Promise,返回resolve()的结果-----------await 是会阻塞后面的代码的 不论是不是promise