关于promise、async/await的理解记录

存在错误望指出

Promise

是什么?

Promise的用法:

new Promise((resolve, reject) => {
  let 表达式 = true;
  if (表达式) {
    resolve();
  } else {
    reject();
  }
}).then(() => {
    // 当执行resolve时则会到这里
    console.log("then");
}).catch(() => {
    // 当执行reject时则会到这里
    console.log("catch");
});

虽然执行了resolvereject之后程序并不会中断,但是两个如果先后执行,则只有先调用的有效。

例如这个代码:

// 控制台打印:	ok   
// 				catch
new Promise((resolve, reject) => {
    reject();
    resolve();
    console.log("ok");
}).then(() => {
    console.log("then");
}).catch(() => {
    console.log("catch");
});

可以在调用方法时传入参数

// 输出:then 可以在这里传递数据
new Promise((resolve, reject) => {
   resolve({
     msg: "可以在这里传递数据",
   });
}).then((res) => {
    console.log("then", res.msg);
});

连续的

// 输出:
// 第一个then OK
// 第二个then 可以直接返回
// 第三个then 当然也可以返回Promise
// 结束
new Promise((resolve, reject) => {
  resolve("OK");
}).then((res) => {
    console.log("第一个then", res);
    return "可以直接返回";
}).then((res) => {
    console.log("第二个then", res);
    return new Promise((resolve) => {
      resolve("当然也可以返回Promise");
    });
}).then((res) => {
    console.log("第三个then", res);
    console.log("结束");
});

为什么?

在以前如api请求、数据库操作、文件读写等涉及到异步处理的时候,通常都要求外部传入一个回调函数。
有时候需要连续做多个异步操作时,就会产生所谓的“回调地狱”
例如:

api请求((api请求返回) => {
  文件读写(文件名, 内容, () => {
    数据库操作(sql, () => {
        // todo
    });
  });
});

在通过Promise改写后,就可以有效缓解或解决这个问题。
如:

new Promise((resolve, reject) => {
    // todo
    api请求((api请求返回) => {
        // todo
        resolve(api请求返回);
    });
}).then((res) => {
    文件读写(文件名, 内容, () => {});
    // todo
    return new Promise((resolve) => {
        // todo
        resolve();
    });
}).then((res) => {
    // todo
    数据库操作(sql, () => {
      // todo
    });
});

从缩进就可以看出二者明显的差异

async/await

是什么?

先看一段代码:

// 输出:Promise { 1 }
async function func() {
  // todo
  return 1;
}
console.log(func());

从以上代码就可以明显看出来,被async修饰过的方法,其返回值是一个Promise对象。

以下是await使用方法:

// 输出:1
(async () => {
  // await 必须运行在被async修饰的方法中
  async function func() {
    // todo
    return 1;
  }
  console.log(await func()); // 直接输出了func的结果值
})();

而其中async部分等效于下面的代码

// 输出:1
(async () => {
  function func() {
    return new Promise((resolve) => {
      resolve(1);
    });
  }
  console.log(await func());
})();

async 可以将一个方法的返回值变成Promise对象
await 方法可以直接取到Promise中传入resolve的值

为什么?

借用前面描述”回调地狱“的例子,使用promise async/await的最佳实践。

// 对原来通过回调完成异步操作的方法使用Promise进行封装
function promise_api请求() {
  return new Promise((resolve) => {
    api请求((api请求返回) => {
      resolve();
    });
  });
}
function promise_文件读写() {
  return new Promise((resolve) => {
    api请求(() => {
      resolve();
    });
  });
}

function promise_数据库操作(sql) {
  return new Promise((resolve) => {
    数据库操作(sql, () => {
      resolve();
    });
  });
}

// 封装完成后即可这样使用了
(async () => {
  await promise_api请求();
  await promise_文件读写();
  await promise_数据库操作(sql);
})();

虽然这里代码量明显增加了不少,但是将这些常用方法进行统一封装,在开发使用时能更有效的降低复杂度,增加了可读性。

总之,用了都说好!

await时reject如何处理?

使用await后,resovle结果值可以直接获取,而reject则会抛出异常。使用try/catch即可

function promise_api请求() {
  return new Promise((resolve, reject) => {
    api请求((api请求返回) => {
      reject();
    });
  });
}

(async () => {
  try {
    await promise_api请求();
  } catch (e) {
    // todo 将会执行这里的代码
  }
})();
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值