前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >消费者怎么看待 then, catch, finally

消费者怎么看待 then, catch, finally

作者头像
公众号---人生代码
发布2021-03-16 16:17:13
9870
发布2021-03-16 16:17:13
举报
文章被收录于专栏:人生代码

消费者:then,catch,finally

昨天讲了关于 Promise 的理解,有人在下面评论说要我出关于源码的解析,能力有限只能循序渐进了,我们还是先把基础的搞明白,再逐步深入。

Promise对象充当执行者(“产生代码”或“singer”)和消费函数(“fans”)之间的链接,它们将接收结果或错误。使用.then、.catch和.finally方法可以注册(订阅)消费函数。

then

最重要,最基本的是 then 。

他的的语法是:

代码语言:javascript
复制
promise.then(
  function(result) { /* handle a successful result */ },
  function(error) { /* handle an error */ }
);

then的第一个参数是一个函数,它在promise被解析时运行,并接收结果。

then的第二个参数是一个函数,当promise被拒绝时运行,并接收错误。

例如,以下是人们对成功解决的反应:

代码语言:javascript
复制
let promise = new Promise(function(resolve, reject) {
  setTimeout(() => resolve("done!"), 1000);
});

// resolve runs the first function in .then
promise.then(
  result => alert(result), // shows "done!" after 1 second
  error => alert(error) // doesn't run
);

执行了第一个函数。

在被拒绝的情况下,第二个

代码语言:javascript
复制
let promise = new Promise(function(resolve, reject) {
  setTimeout(() => reject(new Error("Whoops!")), 1000);
});

// reject runs the second function in .then
promise.then(
  result => alert(result), // doesn't run
  error => alert(error) // shows "Error: Whoops!" after 1 second
);

如果我们只对成功完成感兴趣,那么我们只能为.then提供一个函数参数:

代码语言:javascript
复制
let promise = new Promise(resolve => {
  setTimeout(() => resolve("done!"), 1000);
});

promise.then(alert); // shows "done!" after 1 second

catch

如果我们只对错误感兴趣,那么可以使用null作为第一个参数:.then(null, errorHandlingFunction)。或者我们可以使用.catch(errorHandlingFunction),两者完全相同:

代码语言:javascript
复制
let promise = new Promise((resolve, reject) => {
  setTimeout(() => reject(new Error("Whoops!")), 1000);
});

// .catch(f) is the same as promise.then(null, f)
promise.catch(alert); // shows "Error: Whoops!" after 1 second

调用.catch(f)完全是对.then(null, f)的模拟,它只是一个简写。

finally

就像在一个普通的try{…} catch{…}终于有了承诺。

调用.finally(f)类似于.then(f, f),因为f总是在promise被解决时运行:无论是resolve还是reject。

finally是一个很好的处理程序,用于执行清理,例如停止我们的加载指示器,因为它们不再需要了,无论结果是什么。

是这样的:

代码语言:javascript
复制
new Promise((resolve, reject) => {
  /* do something that takes time, and then call resolve/reject */
})
  // runs when the promise is settled, doesn't matter successfully or not
  .finally(() => stop loading indicator)
  // so the loading indicator is always stopped before we process the result/error
  .then(result => show result, err => show error)

也就是说,finally(f)并不是then(f,f)的别名。有一些细微的区别:

finally处理程序没有参数。在最后,我们不知道诺言是否成功。没关系,因为我们的任务通常是执行“一般的”收尾过程。

finally处理程序将结果和错误传递给下一个处理程序。

例如,这里的结果被传递给finally:

代码语言:javascript
复制
new Promise((resolve, reject) => {
  setTimeout(() => resolve("result"), 2000)
})
  .finally(() => alert("Promise ready"))
  .then(result => alert(result)); // <-- .then handles the result

在promise中有一个错误,最后传递给catch:

代码语言:javascript
复制
new Promise((resolve, reject) => {
  throw new Error("error");
})
  .finally(() => alert("Promise ready"))
  .catch(err => alert(err));  // <-- .catch handles the error object

例子:loadScript

我们在前一章中使用了loadScript函数来加载脚本。

下面是基于回调的变体,只是为了提醒我们:

代码语言:javascript
复制
function loadScript(src, callback) {
  let script = document.createElement('script');
  script.src = src;

  script.onload = () => callback(null, script);
  script.onerror = () => callback(new Error(`Script load error for ${src}`));

  document.head.append(script);
}

我们用 Promise 重写一下。

新的函数loadScript不需要回调。相反,它将创建并返回一个Promise对象,该对象将在加载完成时解析。外部代码可以使用.then向其添加处理程序(订阅函数):

代码语言:javascript
复制
function loadScript(src) {
  return new Promise(function(resolve, reject) {
    let script = document.createElement('script');
    script.src = src;

    script.onload = () => resolve(script);
    script.onerror = () => reject(new Error(`Script load error for ${src}`));

    document.head.append(script);
  });
}

用法

代码语言:javascript
复制
let promise = loadScript("https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js");

promise.then(
  script => alert(`${script.src} is loaded!`),
  error => alert(`Error: ${error.message}`)
);

promise.then(script => alert('Another handler...'));
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CryptoCode 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 消费者:then,catch,finally
  • then
  • catch
  • finally
  • 例子:loadScript
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档