JavaScript异步编程完全理解:从回调到Promise再到async
JavaScript异步编程完全理解:从回调到Promise再到async
JavaScript的异步编程是前端新手最头疼的部分。代码不按顺序执行让人很困惑。理解异步之前我们先理解为什么需要异步这个机制。
JavaScript的单线程特性
JavaScript是单线程语言,一次只能做一件事。但浏览器中经常需要等待用户点击或者等待网络请求返回。如果JavaScript是同步执行的,那等待的这段时间整个页面都会卡住无法操作。
解决方案就是异步。把需要等待的操作交给其他模块处理,JavaScript继续往下执行。等操作完成后再回来执行对应的回调函数。这个过程不阻塞主线程,所以页面不会卡住。
事件循环是JavaScript处理异步的机制。调用栈执行同步代码,遇到异步操作就把回调函数交给对应的Web API处理。Web API处理完成后把回调函数放到任务队列中。调用栈清空后从任务队列取出回调函数执行。这个过程不断循环就是事件循环。
从回调函数到Promise
回调函数是最早的处理异步的方式。异步操作完成后调用传入的回调函数。简单场景下很好用,但多个异步操作嵌套时就出现了回调地狱。三个网络请求嵌套在一起的代码非常难看也非常难维护。
Promise就是解决回调地狱的方案。Promise有三种状态,pending是进行中,fulfilled是成功完成,rejected是失败。状态一旦改变就不可以再变。
使用Promise时then方法处理成功结果,catch方法处理错误。多个异步操作可以用then链式调用,每一层都扁平展开不用嵌套。async函数返回一个Promise,await关键字可以暂停async函数的执行直到Promise完成。
async等待异步操作完成
async和await让异步代码看起来像同步代码。函数前面加async关键字表示这个函数内部有异步操作。await关键字放在一个Promise前面,代码会在这里暂停等待Promise完成,然后继续往下执行。
错误处理使用try catch包裹await调用。这和同步代码的错误处理方式完全一样。这是async最大的优势,统一了错误处理模式。
写在最后
异步编程理解的关键是记住一点,JavaScript一次只能做一件事但可以把需要等待的事情交给别人,等结果回来后继续处理。把这个核心逻辑理解清楚后再去学Promise和async就顺了。从回调开始理解为什么需要Promise,从Promise开始理解为什么需要async。