1. promise 和 async await区别
-
概念
Promise 是异步编程的一种解决方案,比传统的解决方案--回调函数和事件--更合理更强大,简单地说,Promise好比容器,里面存在着一些未来才会执行完毕(异步)的事件和结果,而这些结果一旦生成是无法改变的。
async await 也是异步编程的一种解决方案,他遵循的是Generator 函数的语法糖,他拥有内置执行器,不需要额外的调用直接会自动执行并输出结果,它返回的是一个Promise对象。
-
两者的区别
- Promise的出现解决了传统callback函数导致的“地域回调”问题,但它的语法导致了它向纵向发展行成了一个回调链,遇到复杂的业务场景,这样的语法显然也是不美观的。而async await代码看起来会简洁些,使得异步代码看起来像同步代码,await的本质是可以提供等同于”同步效果“的等待异步返回能力的语法糖,只有这一句代码执行完,才会执行下一句。
- async await与Promise一样,是非阻塞的。
- async await是基于Promise实现的,可以说是改良版的Promise,它不能用于普通的回调函数。
2. defer和async区别
区别主要在于一个执行时间,defer会在文档解析完之后执行,并且多个defer会按照顺序执行,而async则是在js加载好之后就会执行,并且多个async,哪个加载好就执行哪个
-
解析
在没有defer或者async的情况下:会立即执行脚本,所以通常建议把script放在body最后
<script src="script.js"></script>
async: 有async的话,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。
但是多个js文件的加载顺序不会按照书写顺序进行
<script async src="script.js"></script>
derer: 有derer的话,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成,并且多个defer会按照顺序进行加载。
<script defer src="script.js"></script>
编辑
-
总结
- defer和async都是异步加载外部JS文件
- defer和async的差别在于脚本下载完成之后何时执行,显然defer是更接近需求的
- async不保证脚本的执行顺序
- async在外部JS加载完毕之后,浏览器空闲时触发执行
- defer是在外部JS加载完毕之后,整个文档解析完成后触发执行
- defer更像是将
3. 同步和异步
-
同步
指在主线程上排队执行的任务,只有前一个任务执行完后才能继续执行下一个任务。
也就是调用开始,必须调用返回结果才能继续往后执行。程序的执行顺序和任务的排列顺序是一致的。
-
异步
异步任务是指不进入主线程,而进入任务队列的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才能进入主线程。
每一个任务有一个或多个 回调函数。前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行。
任务的执行和任务的排列是不一致的,是异步的。
我们常用的setTimeout和setInterval函数,Ajax都是异步操作。
4. 实现异步的方法
回调函数(Callback)、事件监听、发布订阅、Promise/A+、生成器Generators/ yield、async/await
- JS 异步编程进化史:callback -> promise -> generator -> async + await
- async/await 函数的实现,就是将 Generator 函数和自动执行器,包装在一个函数里。
- async/await可以说是异步终极解决方案了。
(1)async/await函数相对于Promise,优势体现在:
处理 then 的调用链,能够更清晰准确的写出代码;并且也能优雅地解决回调地狱问题。
当然async/await函数也存在一些缺点,因为 await 将异步代码改造成了同步代码,如果多个异步代码没有依赖性却使用了 await 会导致性能上的降低,代码没有依赖性的话,完全可以使用 Promise.all 的方式。
(2)async/await函数对 Generator 函数的改进,体现在以下三点:
内置执行器。 Generator 函数的执行必须靠执行器,所以才有了 co 函数库,而 async 函数自带执行器。也就是说,async 函数的执行,与普通函数一模一样,只要一行。
更广的适用性。 co 函数库约定,yield 命令后面只能是 Thunk 函数或 Promise 对象,而 async 函数的 await 命令后面,可以跟 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作) 。
更好的语义。 async 和 await,比起星号和 yield,语义更清楚了。async 表示函数里有异步操作,await 表示紧跟在后面的表达式需要等待结果。