异步概念
-
异步是与同步相对的概念。
-
异步编程技术使你的程序可以在执行一个可能长期运行的任务的同时继续对其他事件做出反应而不必等待任务完成。与此同时,你的程序也将在任务完成后显示结果。
-
在我们学习的传统单线程编程中,程序的运行是同步的(同步不意味着所有步骤同时运行,而是指步骤在一个控制流序列中按顺序执行)。而异步的概念则是不保证同步的概念,也就是说,一个异步过程的执行将不再与原有的序列有顺序关系。
简单来理解就是:同步按你的代码顺序执行,异步不按照代码顺序执行,异步的执行效率更高。 -
现在有一个按钮,如果我们设置它的 onclick 事件为一个死循环,那么当这个按钮按下,整个网页将失去响应。
为了避免这种情况的发生,我们常常用子线程来完成一些可能消耗时间足够长以至于被用户察觉的事情
Promise
Promise让我们能够把异步操作最终的成功返回值或者失败原因和相应的处理程序关联起来。这样使得异步方法可以像同步方法那样返回值:异步方法并不会立即返回最终的值,而是会返回一个 promise,以便在未来某个时候把值交给使用者。
Promise的三个状态
- 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
- 已兑现(fulfilled):意味着操作成功完成。
- 已拒绝(rejected):意味着操作失败。
当这些情况之一发生时,我们用 promise 的 then 方法排列起来的相关处理程序就会被调用。如果 promise 在一个相应的处理程序被绑定时就已经被兑现或被拒绝了,那么这个处理程序也同样会被调用,因此在完成异步操作和绑定处理方法之间不存在竞态条件。
Promise 是现代 JavaScript 中异步编程的基础,是一个由异步函数返回的可以向我们指示当前操作所处的状态的对象。
Promise特点
对象的状态不受外界影响
Promise对象代表一个异步操作,有三种状态
一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise对象的状态改变,只有两种可能:
- 从Pending变为Resolved
- 从Pending变为Rejected
Promise对象的缺点:
无法取消Promise,一旦新建它就会立即执行,无法中途取消。
如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成。)
Promise基本用法
(1)使用new实例化一个Promise对象,Promise的构造函数中传递一个参数。这个参数是一个函数,该函数用于处理异步任务。
(2)并且传入两个参数:resolve和reject,分别表示异步执行成功后的回调函数和异步执行失败后的回调函数;
(3)通过 promise.then() 处理返回结果。这里的 p 指的是 Promise实例。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
// 第一步:model层的接口封装
const promise = new Promise((resolve, reject) => {
// 这里做异步任务(比如ajax 请求接口。这里暂时用定时器代替)
setTimeout(function() {
var data = { retCode: 0, msg: 'qianguyihao' }; // 接口返回的数据
if (data.retCode == 0) {
// 接口请求成功时调用
resolve(data);
} else {
// 接口请求失败时调用
reject({ retCode: -1, msg: 'network error' });
}
}, 100);
});
// 第二步:业务层的接口调用。这里的 data 就是 从 resolve 和 reject 传过来的,也就是从接口拿到的数据
promise.then(data => {
// 从 resolve 获取正常结果
console.log(data);
}).catch(data => {
// 从 reject 获取异常结果
console.log(data);
});
</script>
</body>
</html>
await/async
await有两个作用,一是作为求值关键字,二是将异步操作变成同步操作;如果方法中使用了await,那么在方法前面必须加上async
- 作为求值关键字,await后面可以跟Promise或表达式,可以直接获取Promise中的值或表达式的值
- 将异步操作变成同步操作
await可以阻塞当前线程,将异步操作变成同步,被阻塞的线程并没有被空闲,而是去执行其他的操作
async的作用是将方法的返回值封装成Promise