JS异步编程
并发(concurrency)和并行(parallelism)区别
- 并发是宏观概念,我分别有任务 A 和任务 B,在一段时间内通过任务间的切换完成了这两个任务,这种情况就可以称之为并发。
- 并行是微观概念,假设 cpu 中存在两个核心,那么我就可以同时完成任务 A、B。同时完成多个任务的情况就可以称之为并行。
回调函数(Callback)
解决回调地狱的方法(异步编程)
-
Generator
-
Promise
-
async 及 await
-
常用定时器函数
Generator
-
Generator 最大的特点就是可以控制函数的执行。
@H_404_21@function *foo(x) { let y = 2 * (yield (x + 1)) let z = yield (y / 3) return (x + y + z) } let it = foo(5) console.log(it.next()) // => {value: 6, done: false} console.log(it.next(12)) // => {value: 8, done:false} console.log(it.next(13)) // => {value: 42, done:true}
Promise
-
三种状态:等待中(pending);完成了 (resolved);拒绝了(rejected)。状态一旦改变成其他状态就不能再次改变。
-
在构造 Promise 的时候,构造函数内部的代码是立即执行的。
@H_404_21@new Promise((resolve, reject) => { console.log('new Promise') resolve('success') }) console.log('finifsh') // new Promise -> finifsh
-
Promise 实现了链式调用,也就是说每次调用 then 之后返回的都是一个 Promise ,并且是一个全新的 Promise ,原因也是因为状态不可变。如果你在 then 中 使用了 return ,那么 return 的值会被 Promise.resolve() 包装。
@H_404[email protected](1) .then(res => { console.log(res) // => 1 return 2 // 包装成 Promise.resolve(2) }) .then(res => { console.log(res) // => 2 })
async 及 await(异步终极解决方案)
-
一个函数如果加上 async ,那么该函数就会返回一个 Promise。
@H_404_21@async function test() { return "1" } console.log(test()) // -> Promise {<resolved>: "1"}
-
async 就是将函数返回值使用 Promise.resolve() 包裹了下,和 then中处理返回值一样,并且 await 只能配套async 使用。
@H_404_21@async function test() { let value = await sleep() }
-
优点在于处理 then 的调用链,能够更清晰准确的写出代码,毕竟写一大堆 then 也很恶心,并且也能优雅地解决回调地狱问题。
-
缺点在于 await 将异步代码改造成了同步代码,如果多个异步代码没有依赖性却使用了 await 会导致性能上的降低。
@H_404_21@let a = 0 let b = async () => { a = a + await 10 console.log('2', a) // -> '2' 10 } b() a++ console.log('1', a) // -> '1' 1
解释:
常用定时器(setTimeout、setInterval、requestAnimationFrame)
- setTimeout 是延时多久,那就应该是多久后执行是错误的。因为JS是单线程执行的,如果前面的代码影响了性能,就会导致 setTimeout不会按期执行。
- setInterval(不建议使用)是每隔一段时间执行一次回调函数。由于其不能保证在预期的时间执行任务而且存在执行累积的问题,通常来说不建议使用 setInterval。
- 如果定时器执行过程中出现了耗时操作,多个回调函数会在耗时操作结束以后同时执行,这样可能就会带来性能上的问题。
- requestAnimationFrame是完成循环定时器的需求。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。