# Promise (重点)
# 简介
- Promise对象代表一个异步操作,有三种状态:
pending
(进行中)、fulfilled
(已成功)和rejected
(已失败) - 一旦状态改变,就不会再变。Promise对象的状态改变,只有两种可能:从
pending
变为fulfilled
和从pending
变为rejected
。 - 缺点:首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
# 用法
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise.then(function(value) {
//resolve 结果
// success
}.catch(function(error) {
//error catch捕获异常
console.log('发生错误!', error);
}).finally(()=>{
//do something 不管状态如何都执行
})
Promise.all()和race() 用于多个Promise示例,包装成新的Promise示例
const p = Promise.all([p1, p2, p3]);
/**
1.只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
2. 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
*/
const race = Promise.race([p1, p2, p3]);
/**
只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
*/
# Iterator
# 概念
遍历器(Iterator
)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator
接口,就可以完成遍历操作
Iterator
的作用有三个:
- 一是为各种数据结构,提供一个统一的、简便的访问接口;
- 二是使得数据结构的成员能够按某种次序排列;
- 三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。
原生具备 Iterator
接口的数据结构如下
- Array
- Map
- Set
- String
- TypedArray
- 函数的arguments对象
- NodeList对象
调用Iterator接口的场合
- 解构赋值
- 扩展运算符
...
yield*
,后面跟可遍历的结构,它会调用该结构的遍历器接口for...of
Array.from()
Promise.all()
,Promise.race()
Map(), Set(), WeakMap(), WeakSet()
# Generator
# 概念
Generator 函数是一个普通函数,但是有两个特征。一是,function
关键字与函数名之间有一个星号;二是,函数体内部使用yield
表达式,定义不同的内部状态,调用遍历器对象的next
方法,使得指针移向下一个状态
# 用法
function* g() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = g();
hw.next()
//{value:'hello',done:false}
返回一个遍历器,可以用for of
循环,...
运算,解构
function* foo() {
yield 1;
yield 2;
yield 3;
return 6;
}
// 扩展运算符
[...foo()] // [1, 2,3]
// Array.from 方法
Array.from(foo()) // [1, 2,3]
// 解构赋值
let [x, y] = foo();
x // 1
y // 2
for (let v of foo()) {
console.log(v);
}
// 1 2 3
co模块 可以自动执行 Generator 函数
# async (重点)
# 含义
async 是Generator 函数的语法糖,把*
换成async
,yield
换成await
,并且内置执行器,返回值是Promise对象
(python 也有差不多的语法 async await)
# 用法
// 函数声明
async function foo() {}
// 函数表达式
const foo = async function () {};
// 对象的方法
let obj = { async foo() {} };
obj.foo().then(...)
// Class 的方法
class Storage {
constructor() {
this.cachePromise = caches.open('avatars');
}
async getAvatar(name) {
const cache = await this.cachePromise;
return cache.match(`/avatars/${name}.jpg`);
}
}
const storage = new Storage();
storage.getAvatar('jake').then(…);
// 箭头函数
const foo = async () => {};
# 错误处理
await后面的异步操作出错,那么等同于async函数返回的 Promise 对象被reject。
f()
.then(v => console.log(v))
.catch(e => console.log(e))
//放在try...catch代码块
async function main() {
try {
const val1 = await firstStep();
const val2 = await secondStep(val1);
const val3 = await thirdStep(val1, val2);
console.log('Final: ', val3);
}
catch (err) {
console.error(err);
}
}
# 多个并发
let [foo, bar] = await Promise.all([getFoo(), getBar()]);
async
和 await
相比直接使用 Promise
来说,优势在于处理 then
的调用链,能够更清晰准确的写出代码。缺点在于滥用 await
可能会导致性能问题,因为 await
会阻塞代码,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成,导致代码失去了并发性
← Proxy Class (重点) →