Promise 链式调用

一个 Promise 必然处于以下几种状态之一:

  • 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled): 意味着操作成功完成。
  • 已拒绝(rejected): 意味着操作失败。

方法

Promise.resolve

1
2
3
4
5
6
7
8
Promise.resolve("Success").then(
function (value) {
console.log(value); // "Success"
},
function (value) {
// 不会被调用
}
);

Promise.reject

1
2
3
4
5
6
7
8
Promise.reject(new Error("fail")).then(
function () {
// 不会被调用
},
function (error) {
console.error(error); // Stacktrace
}
);

Promise.prototype.then()

1
p.then(onFulfilled[, onRejected]);

示例:

1
2
3
4
5
6
7
8
p.then(
(value) => {
// fulfillment
},
(reason) => {
// rejection
}
);

Promise.prototype.catch()

catch() 方法返回一个 Promise,并且处理拒绝的情况。它的行为与调用 Promise.prototype.then(undefined, onRejected) 相同。 (事实上, calling obj.catch(onRejected) 内部 calls obj.then(undefined, onRejected)).

1
p.catch(onRejected);

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
p.catch(function (reason) {
// 拒绝
});

function catchPro() {
Promise.resolve()
.then(() => {
// 使 .then() 返回一个 rejected promise
throw new Error("Oh no!");
})
.catch((error) => {
console.log("onRejected function called: " + error.message);
})
.then(() => {
console.log(
"I am always called even if the prior then's promise rejects"
);
});
}

链式调用

then 方法返回一个 Promise 对象,其允许方法链

你可以传递一个匿名函数给 then,并且,如果它返回一个 Promise,一个等价的 Promise 将暴露给后续的方法链。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function foo() {
Promise.resolve("foo")
// 1. 接收 "foo" 并与 "bar" 拼接,并将其结果做为下一个 resolve 返回。
.then(function (string) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
string += "bar";
resolve(string);
}, 1);
});
})

// 2. 接收 "foobar", 放入一个异步函数中处理该字符串
// 并将其打印到控制台中, 但是不将处理后的字符串返回到下一个。
.then(function (string) {
setTimeout(function () {
string += "baz";
console.log(string);
}, 1);
return string;
})
// 3. 打印本节中代码将如何运行的帮助消息,
// 字符串实际上是由上一个回调函数之前的那块异步代码处理的。
.then(function (string) {
// 注意 `string` 这时不会存在 'baz'。
// 因为这是发生在我们通过 setTimeout 模拟的异步函数中。
console.log("then3", string);
});

// logs, in order:
// foobar
// foobarbaz
}

当一个值只是从一个 then 内部返回时,它将等价地返回 Promise.resolve(<由被调用的处理程序返回的值>)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function thenToThen() {
var p2 = new Promise(function (resolve, reject) {
resolve(1);
});

p2.then(function (value) {
console.log(value); // 1
return value + 1;
}).then(function (value) {
console.log(value + " - A synchronous value works");
});

p2.then(function (value) {
console.log(value); // 1
});

// 1
// 1
// 2 - A synchronous value works
}

如果函数抛出错误或返回一个拒绝的 Promise,则 then 将返回一个拒绝的 Promise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function throwToReject() {
Promise.resolve()
.then(() => {
// 使 .then() 返回一个 rejected promise
throw new Error("Oh no!");
})
.then(
() => {
console.log("Not called.");
},
(error) => {
console.error("onRejected function called: " + error.message); // onRejected function called: Oh no!
}
)
.catch((err) => {
console.error("111");
});
}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
new Promise(function (resolve, reject) {
resolve("Success");
})
.then(function (value) {
console.log("then1", value); // Success
throw new Error("fail");
// return value;
})
.catch(function (e) {
console.log("catch1", e.message); // 上一个 then 没有抛错时没有任何输出
// return Promise.resolve("fail");
// return "fail";
throw new Error("catch");
})
.then(
function (value) {
console.log("then3", value); // Success
},
function (err) {
// 只有上一个为 onrejected 时才会被调用
console.log("catch2", err.message); // 不会被调用,错误已被 catch 捕捉,且 return 出来的是 resolve
}
);
// then1 Success
// catch1 fail
// catch2 catch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
new Promise(function (resolve, reject) {
resolve("Success");
})
.then(function (value) {
console.log("then1", value); // Success
// throw new Error("fail");
return value;
})
.then(
function () {
console.log("then23");
},
function (e) {
console.log(e.message); // 上一个 then 没有抛错时没有任何输出
// return Promise.resolve("fail");
// return "fail2";
throw new Error("catch");
}
)
.then(
function (value) {
console.log(value); // Success
},
function () {
// 只有上一个为 onrejected 时才会被调用
console.log("catch2", err.message);
}
);
// then1 Success
// then23
// undefined
function p1(data) {
return new Promise((resolve, reject) => {
resolve(data);
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function f1() {
p1({ code: 0 })
.then((res) => {
// return { ...res, msg: "F1 回调成功" };
return new Promise((resolve, reject) => {
if (res.code === 0) {
resolve({ ...res, msg: "F1 回调成功" });
// return { ...res, msg: "F1 回调成功" }; // 在 promise 内部只能使用 resolve 向下传递参数,不能用 return
} else {
return f2();
}
});
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function f2() {
p1({ code: 20 })
.then((res) => {
if (res.code === 0) {
// 当一个值只是从一个 then 内部返回时,它将等价地返回 Promise.resolve(<由被调用的处理程序返回的值>)。
return { ...res, msg: "F2 回调成功" };
} else {
// new Error([message[, fileName[, lineNumber]]]) // message:可选,字符串,描述错误的信息,如果非字符串会调用 toString()方法。
// throw new Error(JSON.stringify({ ...res, msg: "F2 code 错误" })); // F2 Error: {"code":20,"msg":"F2 code 错误"}
return Promise.reject({ ...res, msg: "F2 code 错误" }); // F2 { code: 20, msg: 'F2 code 错误' }
}
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log("F2 ", err);
});
}