多个 Promise 按序执行
有 4 个返回 Promise 对象的函数 ABCD,现在想让这 4 个 Promise 顺序执行:
const isA = true;
const isB = true;
const isC = true;
const isD = true;
function A() {
return new Promise((resolve, reject) => {
console.log("running A");
setTimeout(() => {
if (isA) {
resolve("A success");
} else {
reject("A fail");
}
}, 1000);
});
}
function B() {
return new Promise((resolve, reject) => {
console.log("running B");
setTimeout(() => {
if (isB) {
resolve("B success");
} else {
reject("B fail");
}
}, 1000);
});
}
function C() {
return new Promise((resolve, reject) => {
console.log("running C");
setTimeout(() => {
if (isC) {
resolve("C success");
} else {
reject("C fail");
}
}, 1000);
});
}
function D() {
return new Promise((resolve, reject) => {
console.log("running D");
setTimeout(() => {
if (isD) {
resolve("D success");
} else {
reject("D fail");
}
}, 1000);
});
}
方法一:链式调用 then
前一个 Promise 的 then 返回下一个 Promise 实例,然后链式调用 then
A().then(
(res) => {
console.log(res);
return B();
}
).then(
(res) => {
console.log(res);
return C();
}
).then(
(res) => {
console.log(res);
return D();
}
).then(
(res) => {
console.log(res);
}
);
方法二:await
使用 async 和 await:
async 函数是使用async关键字声明的函数。async 函数是 AsyncFunction 构造函数的实例,并且其中允许使用 await 关键字。async 和 await 关键字让我们可以用一种更简洁的方式写出基于 Promise 的异步行为,而无需刻意地链式调用 promise
await 操作符用于等待一个 Promise 兑现并获取它兑现之后的值。它只能在 async 函数或者模块顶层中使用
await 可以让异步的操作获得同步的写法
async function ABCD() {
const resA = await A(); // 同步的写法,但实际上是异步的
console.log(resA);
const resB = await B();
console.log(resB);
const resC = await C();
console.log(resC);
const resD = await D();
console.log(resD);
}
ABCD();
async 返回值
async function fn1() {
console.log("running fn1");
return 0;
}
console.log(fn1()); // Promise { 0 }
function fn2() {
fn1().then(
() => console.log("fn1 success")
).catch(
() => console.log("fn1 fail")
);
}
fn2();
运行结果:
[root@nodejs01 vivid_timing_rpt]# node foo.js
running fn1
Promise { 0 }
running fn1
fn1 success
可见,async函数会返回一个 Promise 实例。Promise 实例的状态就看函数体有没有出错,如果没有出错,那么状态就是 fullid,如果执行中出错了那么就是 rejected
例如,在上面代码中引入错误,就会返回一个 rejected 的 Promise:
async function fn1() {
console.log("running fn1");
let a = b;
return 0;
}
显示地返回一个 Promise 也是可以的:
async function fn1() {
return new Promise((resolve, reject) => {
console.log("running fn1");
resolve(0);
});
}
async 错误处理
使用 try catch 处理错误:
async function fn1() {
console.log("running fn1");
let a = b;
return 0;
}
async function fn2() {
let res = 0;
try {
res = await fn1();
console.log("fn1 success: ", res);
} catch (err) {
console.log("fn1 fail: ", err);
}
}
fn2();
[root@nodejs01 vivid_timing_rpt]# node foo.js
running fn1
fn1 fail: ReferenceError: b is not defined