深入浅析Nodejs异步编程中的Promise
【推荐学习:《nodejs 教程》】
什么是 Promise
Promise 是一种异步编程的解决方案!
- 当前事件循环得不到的结果,但未来的事件循环会给到你结果
- 是一个状态机
- PEngding
- resolved
- reejectd
从代码看状态流转是怎样的
pending 到 resolve 的流转测试
(function () {
const res = new Promise((resolve, reject) =>
{
setTimeout(() =>
{
resolve();
}
, 500);
}
);
console.LOG("500ms", res);
setTimeout(() =>
{
console.log("800ms", res);
}
, 800);
}
)();
打印出如下内容
结果是符合我们的预期的
- 我们无法立即获取
promise的结果,此时promise处于pending状态 - 必须等待一段时间过后才能获取
promise的结果,此时promise处于fulfilled状态
pending 到 reject 的流转测试
(function () {
const res = new Promise((resolve, reject) =>
{
setTimeout(() =>
{
reject(new Error("error"));
}
, 500);
}
);
console.log("500ms", res);
setTimeout(() =>
{
console.log("800ms", res);
}
, 800);
}
)();
打印出如下内容
结果是符合我们的预期的
- 我们无法立即获取
promise的结果,此时promise处于pending状态 - 必须等待一段时间过后才能获取
promise的结果,此时promise处于reject状态
注意:如果当 pengding 状态进入到 reject 状态,这个错误又没有正确捕获的话,这个错误就会被抛到 JS 的全局
reslove 状态流转到 reject 状态测试
(function () {
const res = new Promise((resolve, reject) =>
{
setTimeout(() =>
{
resolve();
}
, 300);
setTimeout(() =>
{
reject(new Error("error"));
}
, 500);
}
);
console.log("500ms", res);
setTimeout(() =>
{
console.log("800ms", res);
}
, 800);
}
)();
打印出如下内容
可以发现!
在 300ms 的时候promise的状态已经切换到了resolve, 切换后永远也无法到达reject状态
pending只能流转到resolve或者reject;resolve和reject不能互相流转;
使用 then,catch 捕获 promise 的结果
(function () {
const res = new Promise((resolve, reject) =>
{
setTimeout(() =>
{
resolve(3);
}
, 300);
}
) .then((result) =>
{
console.log("result", result);
}
) .catch((error) =>
{
console.log("error", error);
}
);
console.log("300ms", res);
setTimeout(() =>
{
console.log("800ms", res);
}
, 800);
}
)();
打印出如下内容
可以发现
then是promise的状态流转到reslove状态可以拿到的结果
(function () {
const res = new Promise((resolve, reject) =>
{
setTimeout(() =>
{
reject(new Error("error-3"));
}
, 300);
}
) .then((result) =>
{
console.log("result", result);
}
) .catch((error) =>
{
console.log("error", error);
}
);
console.log("300ms", res);
setTimeout(() =>
{
console.log("800ms", res);
}
, 800);
}
)();
打印出如下内容
可以发现
catch 是 promise 的状态流转到 reject 状态可以拿到的结果, 并且之前全局的 JS 错误已经可以被 catch 捕获到了
.then .catch 总结
resolved状态的 Promise 会回调后面的第一个.thenrejected状态的 Promise 会回调后面的第一个.catch- 任何一个
rejected状态切后面没有.catch的 Promise 会造成 Js 环境的全局错误
Promise 相比 callback 优秀的地方
解决异步流程控制问题-回调地狱
我们继续之前面试的例子
使用 Promise 改造 之前的 interview 函数
function interview() {
return new Promise(function (resolve, reject) {
setTimeout(() =>
{
if (Math.random() >
0.4) {
// resolve, reject 只能接受一个参数 resolve("success");
}
else {
reject(new Error("fail"));
}
}
, 1000);
}
);
}
(function () {
const res = interview();
res .then((result) =>
{
console.log("面试成功!我笑了");
}
) .catch((error) =>
{
console.log("面试失败!我哭了");
}
);
}
)();
.then 中抛出错误的情况测试
function interview() {
return new Promise(function (resolve, reject) {
setTimeout(() =>
{
if (Math.random() >
0.4) {
// resolve, reject 只能接受一个参数 resolve("success");
}
else {
reject(new Error("fail"));
}
}
, 500);
}
);
}
(function () {
const promsie1 = interview();
const promsie2 = promsie1.then((result) =>
{
throw new Error("面试成功!我笑了,但是我拒绝了");
}
);
setTimeout(() =>
{
console.log("promsie1", promsie1);
console.log("promsie2", promsie2);
}
, 800);
}
)();
以上代码可以看出 ,**.then返回一个全新的 Promise, 此 Promise 的结果状态是由 .then 的回调函数的结果来决定的
- 如果回调函数最终是
throw, 则进入 rejected - 如果回调函数最终是
return,则进入 resolved
.catch 中正常值的情况测试
function interview() {
return new Promise(function (resolve, reject) {
setTimeout(() =>
{
if (Math.random() >
0) {
// resolve, reject 只能接受一个参数 resolve("success");
}
else {
reject(new Error("fail"));
}
}
, 500);
}
);
}
(function () {
const promsie1 = interview();
const promsie2 = promsie1.catch((result) =>
{
return "虽然面试失败,但我还是笑了";
}
);
setTimeout(() =>
{
console.log("promsie1", promsie1);
console.log("promsie2", promsie2);
}
, 800);
}
)();
.catch 返回一个全新的 Promise, 此 Promise 的结果状态是由 .catch 的回调函数的结果来决定的
- 如果回调函数最终是
throw, 则进入 rejected - 如果回调函数最终是
return,则进入 resolved
.catch,.then 里面再返回 Promise
function interview() {
return new Promise(function (resolve, reject) {
setTimeout(() =>
{
if (Math.random() >
0.4) {
// resolve, reject 只能接受一个参数 resolve("success");
}
else {
reject(new Error("fail"));
}
}
, 500);
}
);
}
(function () {
const promsie1 = interview();
const promsie2 = promsie1 .then((result) =>
{
return new Promise(function (resolve, reject) {
setTimeout(() =>
{
resolve("面试成功!,给我400ms 总结一下");
}
, 400);
}
);
}
) .catch((result) =>
{
return new Promise(function (resolve, reject) {
setTimeout(() =>
{
resolve("面试失败,给我400ms 总结一下");
}
, 400);
}
);
}
);
setTimeout(() =>
{
console.log("800ms promsie1", promsie1);
console.log("800ms promsie2", promsie2);
}
, 800);
setTimeout(() =>
{
console.log("1000ms promsie1", promsie1);
console.log("1000ms promsie2", promsie2);
}
, 1000);
}
)();
如果在 .catch,.then 中 返回 Promise, 则会等待此 Promise 的执行结果
如果回调函数最终 return 了 Promise,该 promise 和回调函数的 return 的 Promsie 状态保持一致, 这就表示了可以 在 Promise 的链式调用里面串行的执行多个异步任务!
Promise 实现多轮面试-串行
// round 面试第几轮function interview(round) {
return new Promise(function (resolve, reject) {
setTimeout(() =>
{
if (Math.random() >
0.4) {
// resolve, reject 只能接受一个参数 resolve("success");
}
else {
const error = new Error("fail");
reject({
round, error }
);
}
}
, 500);
}
);
}
(function () {
interview(1) .then(() =>
{
return interview(2);
}
) .then(() =>
{
return interview(3);
}
) .then(() =>
{
console.log("每轮面试都成功!我开心的笑了");
}
) .catch((err) =>
{
console.log(`第${
err.round}
轮面试失败了`);
}
);
}
)();
Promise 的 .then .catch 把回调地狱变成了一段线性的代码!
Promise 实现多加公司面试-并行
// round 面试第几轮function interview(name) {
return new Promise(function (resolve, reject) {
setTimeout(() =>
{
if (Math.random() >
0.4) {
// resolve, reject 只能接受一个参数 resolve("success");
}
else {
const error = new Error("fail");
reject({
name, error }
);
}
}
, 500);
}
);
}
(function () {
Promise.all([interview("tenxun"), interview("ali"), interview("baidu")]) .then(() =>
{
console.log("每家公司都面试成功了");
}
) .catch((err) =>
{
console.log(`面试${
err.name}
失败了`);
}
);
}
)();
更多编程相关知识,请访问:编程视频!!
以上就是深入浅析Nodejs异步编程中的Promise的详细内容,更多请关注其它相关文章!
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 深入浅析Nodejs异步编程中的Promise
本文地址: https://pptw.com/jishu/591788.html
