1. 为什么需要异步编程
JavaScript 是单线程的,意味着它一次只能做一件事。如果所有操作都是同步的,那么一个耗时的操作(如网络请求、读取大文件、定时任务)就会阻塞整个线程,导致页面无响应,用户体验极差。
异步编程就是为了解决这个问题:“发起一个操作,然后立即去做别的事,等这个操作完成后,再回来处理它的结果。” 这样主线程就解放了,不会因为等待而卡住。异步编程解决了js单线程的问题,二我们也要清楚他的运行原理,以及其中牵扯到的一些概念。
2.回调函数
回调函数是最开始的一种处理方法,,他是吧一个函数作为参数传递给另一个函数,在事件循环中,处理完异步任务以后,回调函数发给任务队列,按顺序调用的时候执行该回调函数。
缺点:回调地域
getData(function(a) {
getMoreData(a, function(b) {
getEvenMoreData(b, function(c) {
console.log('最终结果:', c);
});
});
});
当多个异步操作需要顺序执行时,代码会变得层层嵌套,难以维护和阅读。可以使用promise解决。
3.promise
promise又叫期约,是指对尚不存在结果的替身。是Es6新增的引用类型Promise,用于实现一个异步程序执行的机制。Promise是一个有状态的对象,有三个状态:待定Padding,兑现fulfilled/resolve,拒绝rejected,padding是Promise初始状态,然后会变成俩种状态之一,而且俩种状态落实以后不可逆转,,而异步操作成功时,状态变成fulfilled,异步操作发生中断或被阻止。
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = Math.random() > 0.3;
if (success) {
resolve('数据获取成功!');
} else {
reject('获取数据失败!');
}
}, 1000);
});
}
fetchData()
.then((result) => {
console.log('成功:', result);
})
.catch((error) => {
console.error('失败:', error);
});
期约的状态是私有的,任何外部的代码不能修改其内部代码。Promise的异步行为封装异步行为。
Promise.resolve()可以将任何值都实例化不同状态的期约,,包括undefined和错误对象Error,(考核里面有)
Promise.reject()和上面的方法的类似,可以把任何值实例化为一个拒绝的期约并抛出一个拒绝的理由。拒绝的理由就是第一个参数。
4.Async / Await
这是基于 Promise 的语法糖,能用写同步代码的方式来写异步代码,代码变得异常清晰和简洁。
async
:声明一个函数是异步的。这个函数总会返回一个 Promise。如果函数返回值不是 Promise,它会被自动包装成一个 resolved 状态的 Promise。await
:只能在async
函数内部使用。它会“暂停”函数的执行,等待一个 Promise 完成(resolve 或 reject),然后返回其结果。
这个可以用try...catch即可捕捉异步错误。