promise, async/await
Promise是抽象异步处理对象以及对其进行各种操作的组件。
1. 基础
let promise = new Promise(function(resolve, reject) {
// 异步处理
// 处理结束后、调用resolve 或 reject
});
promise.then(resolveFunc).catch(rejectFunc)
// 链式写法
promise.then(resolveFunc1).then(resolveFunc2).catch(rejectFunc)
// promise.catch 等价于 promise.then(null, rejectFunc)
Promise对象有以下三个状态
- has-resolution: resolve
- has-rejection: reject
- unresolve: 刚创建后的初始化状态
一旦状态从unresolve转变成 resolve或者reject后,就不会再发生人话变化,即在 .then 后执行的函数可以肯定地说只会被调用一次。
var promise = new Promise(function (resolve){
console.log("inner promise"); // $1
resolve("resolve");
});
console.log("outer promise 1"); // $2
promise.then(function(value){
console.log(value); // $4
});
console.log("outer promise 2"); // $3
> inner promise
> outer promise1
> outer promise2
> resolve
执行顺序:
- 初始化Promise对象,
$1
被执行 - 紧接着
$2
被执行 - 虽然在调用promise.then时,promise对象已经是确定的状态,但仍会以异步的形式调用。所以先执行
$3
- 异步执行回调函数,
$4
2. Promise Chain执行顺序
2.1 基本执行顺序
let promise = Promise.resolve();
// Promise.resolve() 等价于
// new Promise(function(resolve){
// resolve();
// });
promise.then(taskA).then(taskB).catch(onReject).then(finalTask)
note: onReject和final Task的失败不会触发reject.
2.2 传递参数
function doubleUp(value) {
return value * 2;
}
function increment(value) {
return value + 1;
}
function output(value) {
console.log(value); // => 4: (1 + 1) * 2
}
let promise = Promise.resolve(1);
promise
.then(increment)
.then(doubleUp)
.then(output)
.catch(function(error){
// promise chain中出现异常的时候会被调用
console.error(error);
});
- then, catch之前的传递的参数可以为任意对象
- then函数返回的是一个包装后的Promise对象
标记法
- 点标记法
dot notation
要求对象的属性必须是有效的标识符(在ECMAScript 3中则不能使用保留字) - 中括号标记法
bracket notation
的话,则可以将非合法标识符作为对象的属性名使用
2.3 Promise.all
Promise.all
接收一个 Promise对象的数组作为参数,当这个数组里的所有_Promise对象
全部变为resolve或reject状态的时候,它才会去调用 .then
方法。
3. async 和 wait
async 函数的工作方式
- async 函数总是返回一个 Promise 对象
p
。Promise 对象在 async 函数开始执行时被创建。- 函数体执行过程中,可以通过
return
或throw
终止执行。或者通过await
暂停执行,在这种情况下,通常会在以后继续执行。- 返回 Promise 对象
p
// 1. async 函数总是返回 Promises
async function asyncFunc() {
return "test";
}
asyncFunc().then( (param) => {
console.log(param); // "test"
})
// 2. 通过 await 处理 async 计算的结果和错误
// 2.1 单个
async function asyncFunc() {
let result = await otherAsyncFunc();
console.log(result);
// 等价版本
return otherAsyncFunc().then( (result) => { console.log(result); });
}
// 2.2 串
async function asyncFunc() {
let result1 = await otherAsyncFunc1();
console.log(result1);
let result2 = await otherAsyncFunc2();
console.log(result2);
// 等价版本
return otherAsyncFunc1().then( (result) => { console.log(result); return otherAsyncFunc2()})
.then((result) => { console.log(result) });
}
// 2.3 并行
async function asyncFunc() {
let [result1, result2] = await Promise.all([
otherAsyncFunc1(),
otherAsyncFunc2()
])
console.log(result1, result2);
// 等价版本
return Promise.all([
otherAsyncFunc1(),
otherAsyncFunc2()
]).then( ([result1, result2]) => { console.log(result1, result2); } )
}
// 2.4 错误处理
async function asyncFunc() {
try {
await otherAsyncFunc();
} catch (err) {
console.error(err);
}
// 等价版本
return otherAsyncFunc().catch( (err) => {
console.error(err);
});
}