diff --git a/05-JavaScript基础:异步编程和Ajax/01-单线程和异步.md b/05-JavaScript基础:异步编程和Ajax/01-单线程和异步.md index 7b4d17c..535956a 100644 --- a/05-JavaScript基础:异步编程和Ajax/01-单线程和异步.md +++ b/05-JavaScript基础:异步编程和Ajax/01-单线程和异步.md @@ -34,13 +34,13 @@ setTimeout(() => { 比如说,网络图片的请求,就是一个异步任务。前端如果同时请求多张网络网络图片,谁先请求完成就让谁先显示出来。 -假如网络图片的请求做成同步任务,那就会出大问题,所有图片都得排队加载,如果第一张图片未加载完成,就得卡在那里,造成阻塞,导致其他图片都加载不出来。这肯定是不能接受的。 +假如网络图片的请求做成同步任务,那就会出大问题,所有图片都得排队加载,如果第一张图片未加载完成,就得卡在那里,造成阻塞,导致其他图片都加载不出来。页面看上去也会很卡顿,这肯定是不能接受的。 ### 前端使用异步的场景 什么时候需要**等待**,就什么时候用异步。 -- 定时任务:setTimeout(定时炸弹)、setInterval(循环执行) +- 定时器:setTimeout(定时炸弹)、setInterval(循环执行) - 事件绑定(比如说,按钮绑定点击事件之后,用户爱点不点。我们不可能卡在按钮那里,什么都不做。所以,应该用异步) @@ -59,7 +59,7 @@ js 中常见的接口调用方式,有以下几种: - Fetch - axios -下一篇文章,我们重点讲一下接口调用里的 Ajax,然后在ES6语法中学习 **Promise**。在这之前,我们需要先了解同步任务、异步任务的事件循环机制。 +下一篇文章,我们重点讲一下接口调用里的 Ajax,然后在 ES6 语法中学习 **Promise**。在这之前,我们需要先了解同步任务、异步任务的事件循环机制。 ### 多次异步调用的顺序 @@ -79,7 +79,8 @@ js 中常见的接口调用方式,有以下几种: - 当主线程的任务执行完毕之后,此时主线程处于空闲状态,于是会去读取 Event Queue 中的任务队列,如果有任务,则进入到主线程去执行。 -## 代码示例 + +## 定时器:代码示例 掌握了上面的事件循环原理之后,我们来看几个例子。 @@ -144,8 +145,7 @@ setTimeout(() => { sleep(5000); //表示很耗时的同步任务 ``` -上面的代码中,异步任务不是2秒之后执行,而是等耗时的同步任务执行完毕之后,才执行。那这个异步任务,是在5秒后执行?还是在7秒后执行?这个作业,留给读者你来思考~ - +上面的代码中,异步任务不是 2 秒之后执行,而是等耗时的同步任务执行完毕之后,才执行。那这个异步任务,是在 5 秒后执行?还是在 7 秒后执行?这个作业,留给读者你来思考~ ### 举例 3(较真系列) @@ -157,13 +157,49 @@ setTimeout(() => { 上面的代码中,等到 1 秒之后,真的会执行异步任务吗?其实不是。 -在浏览器中, setTimeout()/ setInterval() 的每调用一次定时器的最小时间间隔是**4ms**,这通常是由于函数嵌套导致(嵌套层级达到一定深度),或者是由于已经执行的setInterval的回调函数阻塞导致的。 +在浏览器中, setTimeout()/ setInterval() 的每调用一次定时器的最小时间间隔是**4ms**,这通常是由于函数嵌套导致(嵌套层级达到一定深度),或者是由于已经执行的 setInterval 的回调函数阻塞导致的。 + +上面的案例中,异步任务需要等待 1004 毫秒之后,才会从 Event Table 进入到 Event Queue。这在面试中也经常被问到。 + +## 异步任务举例 +### 例1:加载图片 + +```js +// 加载图片的异步任务 +function loadImage(file, success, fail) { + const img = new Image(); + img.src = file; + img.onload = () => { + // 图片加载成功 + success(img); + }; + img.onerror = () => { + // 图片加载失败 + fail(new Error('img load fail')); + }; +} + +loadImage( + 'images/qia nguyihao.png', + (img) => { + console.log('图片加载成功'); + document.body.appendChild(img); + img.style.border = 'solid 2px red'; + }, + (error) => { + console.log('图片加载失败'); + console.log(error); + } +); +``` + + +### 例2:定时器计时 + -上面的案例中,异步任务需要等待1004毫秒之后,才会从 Event Table 进入到 Event Queue。这在面试中也经常被问到。 ## 参考链接 - [JS-同步任务,异步任务,微任务,和宏任务](https://github.com/PleaseStartYourPerformance/javaScript/issues/34) - [JS 同步异步宏任务微任务](https://juejin.cn/post/6875605533127081992)、[JavaScript 中事件循环的理解](https://zhuanlan.zhihu.com/p/364475433)、[javascript 事件循环机制](https://github.com/reng99/blogs/issues/34) - [如何实现比 setTimeout 快 80 倍的定时器?](https://mp.weixin.qq.com/s/NqzWkeOhqAU85XPkJu_wCA) -