JS中异步处理执行顺序

在【异步 & 进程 & Promise规范及应用-优快云博客】一文中,介绍了异步与进程的关系,以及promise的规范以及应用,这里对异步执行顺着做一个扩展。

JavaScript是单线程语言,同一时间只能做一件事,只有当前一个任务结束,才会执行下一个任务。假如前一个任务执行时间较长,下一个任务还得等待前一个任务执行完成。

在JS中有同步任务和异步任务,他们之间的执行有一定的顺序。

Event Loop事件循环

关于事件循环,在【异步 & 进程 & Promise规范及应用-优快云博客】一文中也有提到。

在JS中把任务分为同步任务和异步任务:

1、同步任务(synchronous):在主线程(执行栈)中排队执行的任务,只有前一个任务执行完毕,才能执行下一个任务

2、异步任务(asynchronous):在任务队列(task queue)中,当任务队列通知主线程,某个异步任务能够执行了,该任务才会进入主线程(执行栈)中执行。

事件循环机制:

(1)当执行JS代码时,同步任务会被推入执行栈中执行。

(2)当异步操作(setTimeout,promise,XMLHttpRequest等)执行完成时,它们的回调函数会被推入任务队列

(3)检查执行栈是否为空,如果为空,则从任务队列中取出第一个任务,推入执行栈执行。当执行栈中所有同步任务执行完毕,则会读取任务队列,异步任务结束等待状态,进入执行栈,开始执行。任务队列中任务执行完成后,继续回到执行栈进行下一轮任务执行。

任务队列

任务队列(也叫事件队列)分为宏任务队列(macrotask queue)和微任务队列(microtask queue)。JavaScript引擎遵循事件循环机制,在执行完当前宏任务后,会检查微任务队列,执行微任务,然后再取下一个宏任务执行,从而形成了事件循环。【有微则微、无微则宏】

宏任务:所有同步任务、I/O操作、setTimeout、setInterval、setImmediate(Node.js环境)、requestAnimationFrame、事件监听回调函数等

微任务:Promise的then、catch、finally;async/await中的代码;Generator函数、MutationObserver、process.nextTick(Node.js 环境)

特殊任务:

requestAnimationFrame(callback)-仅仅存在于浏览器环境,执行时机在setTimeout之前执行(第一次宏微任务执行完成后,在下一次宏任务之前执行)【与UI渲染

### 控制 JavaScript异步函数执行顺序的最佳实践 #### 使用 `async` 和 `await` 为了更好地控制异步操作的顺序并保持代码可读性和维护性,推荐使用 `async/await` 结构。这种方式可以简化复杂的 Promise 链,并使代码看起来更像同步编程。 ```javascript async function processTasks() { try { const result1 = await taskOne(); console.log('Task One Completed:', result1); const result2 = await taskTwo(result1); console.log('Task Two Completed:', result2); const finalResult = await taskThree(result2); console.log('All Tasks Completed:', finalResult); } catch (error) { console.error('Error occurred during processing tasks', error); } } ``` 这种方法不仅提高了代码的易读性,还使得错误处理更加直观[^1]。 #### 并发执行多个异步任务 当有多个不依赖彼此结果的任务时,可以通过 `Promise.all()` 来并发执行这些任务,从而提高效率: ```javascript function performConcurrentOperations() { const operationPromises = [ asyncOperationOne(), asyncOperationTwo(), asyncOperationThree() ]; return Promise.all(operationPromises).then((results) => { // 所有操作完成后处理结果 results.forEach((result, index) => { console.log(`Operation ${index + 1} completed with result`, result); }); }).catch(error => { console.error('An error occurred while performing concurrent operations.', error); }); } ``` 这允许同时启动多项独立的工作,在它们全部完成后再继续下一步逻辑[^2]。 #### 处理条件性的异步流程 对于那些基于某些条件决定是否要运行特定异步任务的情况,则可以在 `if-else` 或者其他分支语句内嵌入相应的异步调用: ```javascript async function handleConditionalAsyncFlow(condition) { let data; if (condition === 'specific') { data = await specificConditionHandler(); } else { data = await defaultHandler(); } console.log('Handled conditionally based on input:', data); } ``` 通过这种方式可以根据不同的业务场景灵活调整异步工作的流向[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值