React教程: 第15天 Promise简介

本文转载自:众成翻译
译者:iOSDevLog
链接:https://www.zcfy.cc/article/3814
原文:https://www.fullstackreact.com/30-days-of-react/day-15/

这篇文章是30 Days of React系列的一部分。
在本系列中,我们将从最基本的开始,逐步了解开始React所需的所有知识。如果你曾经想学习反应,这是开始的地方!

30 Days of React PDF版本下载:下载超过300页的 PDF

今天,我们将要看看我们需要知道什么来从高层次了解Promises,所以我们可以使用这个非常有用的概念构建我们的应用。

昨天我们将 fetch 库安装到我们的 create-react-app 项目 我们开始 第12天. 今天, 我们将拿起从昨天讨论的概念和Promises的艺术 .

What is a promise(什么是promise)


正如 mozilla 所定义的, Promise对象用于处理异步计算, 其中有一些重要的保证难以用回调方法处理 (更老式的处理异步代码的方法)。

Promise 对象只是围绕一个值的包装, 它在实例化对象时可能也可能不知道, 并提供了一个已知的 (也称为 resolved) 或由于失败原因而不可用 (我们将此称为rejected) 后处理该值的方法 。

使用 Promise 对象使我们有机会将异步操作的最终成功或失败关联到功能 (无论出于何种原因)。它还允许我们使用类似于同步的代码来处理这些复杂的场景。

例如, 考虑下面的同步代码, 我们在 javascript 控制台中打印出当前时间:

var currentTime = new Date();
console.log('The current time is: ' + currentTime);

这是相当直接的, 并作为 new Date() 对象表示浏览器知道的时间。现在考虑我们在其他远程机器上使用不同的时钟。例如, 如果我们正在做一个快乐的新年时钟, 这将是伟大的, 能够同步用户的浏览器与其他人使用一个单一的时间值为每个人, 所以没有人错过的落球仪式。。

假设我们有一个方法来处理从远程服务器获取当前时间的 getCurrentTime() 时钟。现在, 我们将用setTimeout() 来表示这一点, 它返回时间 (就像对慢速 api 发出请求一样):

function getCurrentTime() {
  // Get the current 'global' time from an API
  return setTimeout(function() {
    return new Date();
  }, 2000);
}
var currentTime = getCurrentTime()
console.log('The current time is: ' + currentTime);

我们的console.log() 日志值将返回超时处理程序 id, 这绝对不是当前时间。传统上, 我们可以使用回调来更新代码, 以便在可用时间时调用:

function getCurrentTime(callback) {
  // Get the current 'global' time from an API
  return setTimeout(function() {
    var currentTime = new Date();
    callback(currentTime);
  }, 2000);
}
getCurrentTime(function(currentTime) {
  console.log('The current time is: ' + currentTime);
});

如果有其余的错误呢?我们如何捕获错误并定义重试或错误状态?

function getCurrentTime(onSuccess, onFail) {
  // Get the current 'global' time from an API
  return setTimeout(function() {
    // randomly decide if the date is retrieved or not
    var didSucceed = Math.random() >= 0.5;
    if (didSucceed) {
      var currentTime = new Date();
      onSuccess(currentTime);
    } else {
      onFail('Unknown error');
    }
  }, 2000);
}
getCurrentTime(function(currentTime) {
  console.log('The current time is: ' + currentTime);
}, function(error) {
  console.log('There was an error fetching the time');
});

现在, 如果我们想根据第一个请求的值提出请求怎么办?作为一个简短的示例, 让我们再次重用 getCurrentTime() 函数 (就好像它是第二个方法, 但允许我们避免添加另一个复杂的函数):

function getCurrentTime(onSuccess, onFail) {
  // Get the current 'global' time from an API
  return setTimeout(function() {
    // randomly decide if the date is retrieved or not
    var didSucceed = Math.random() >= 0.5;
    console.log(didSucceed);
    if (didSucceed) {
      var currentTime = new Date();
      onSuccess(currentTime);
    } else {
      onFail('Unknown error');
    }
  }, 2000);
}
getCurrentTime(function(currentTime) {
  getCurrentTime(function(newCurrentTime) {
    console.log('The real current time is: ' + currentTime);
  }, function(nestedError) {
    console.log('There was an error fetching the second time');
  })
}, function(error) {
  console.log('There was an error fetching the time');
});

以这种方式处理异步会很快变得复杂。此外, 我们可以从以前的函数调用中获取值, 如果我们只想得到一个… 在处理应用启动时还没有的值时, 有很多棘手的情况需要处理。

Enter Promises(进入Promises)


使用promises, 另一方面帮助我们避免了很多这种复杂性 (虽然不是一个灵丹妙药)。以前的代码(可以称为意大利面代码)可以转换为更整洁、更同步的版本:

function getCurrentTime() {
  // Get the current 'global' time from an API using Promise
  return new Promise((resolve, reject) => {
    setTimeout(function() {
      var didSucceed = Math.random() >= 0.5;
      didSucceed ? resolve(new Date()) : reject('Error');
    }, 2000);
  })
}
getCurrentTime()
  .then(currentTime => getCurrentTime())
  .then(currentTime => {
    console.log('The current time is: ' + currentTime);
    return true;
  })
  .catch(err => console.log('There was an error:' + err))

在这里插入图片描述
上一个源代码示例对发生的事情有一点清晰明了,避免了很多复杂的错误处理/捕获。

为了捕捉成功时的值,我们将使用Promise实例对象上可用的then()函数。无论承诺本身的返回值是什么,都会调用then函数。例如,在上面的例子中,getCurrentTime函数使用currentTime值进行解析(成功完成时),并对返回值(这是另一个承诺)调用then()函数,以此类推。

要捕获在promise链中任何地方发生的错误, 我们可以使用catch() 方法。

我们在上面的例子中使用一个承诺链, 以创建一个链的行动, 被称为一个接一个。 承诺链听起来很复杂, 但基本上很简单。实质上, 我们可以连续地 “同步” 调用多个异步操作。对then()的每次调用都用以前的then() 函数的返回值来调用。

例如, 如果我们想操纵getCurrentTime() 调用的值, 我们可以在链中添加一个链接, 如下所示:

getCurrentTime()
  .then(currentTime => getCurrentTime())
  .then(currentTime => {
    return 'It is now: ' + currentTime;
  })
  // this logs: "It is now: [current time]"
  .then(currentTimeMessage => console.log(currentTimeMessage))
  .catch(err => console.log('There was an error:' + err))

Single-use guarantee(单使用保证)


promise在任何特定的时间都只应该在三种状态之一:

  • pending(待定)
  • fulfilled (resolved)(已完成 (已解决))
  • rejected (error)(已拒绝 (错误))

一个待定的承诺只能导致一个满足状态或一个被拒绝的状态 一次且仅一次, 这可以避免一些相当复杂的错误场景。这意味着, 我们只能返回一个承诺一次。如果我们想重新运行一个使用承诺的函数, 我们需要创建一个新的。

Creating a promise(创建一个承诺)


我们可以使用 Promise构造函数来创建新的承诺 (如上面的示例所示)。它接受一个有两个参数来运行的函数:

  • onSuccess (or resolve) 函数将在成功解析后被调用
  • onFail (or reject) 函数在失败拒绝后被调用

从上面回顾我们的函数, 我们可以看到, 如果请求成功, 我们调用 resolve() 函数, 如果该方法返回错误条件, 则调用 reject() 函数。

var promise = new Promise(function(resolve, reject) {
  // call resolve if the method succeeds
  resolve(true);
})
promise.then(bool => console.log('Bool is true'))

现在我们知道了什么是promises, 如何使用, 以及如何创建它们, 我们实际上可以使用昨天安装的 fetch() 库。


上一章:获取远程数据
下一章:显示远程数据


本教程系列的完整源代码可以在 GitHub repo, 上找到,其中包含所有样式和代码示例。
如果在任何时候你感到困扰,有进一步的问题,请随时通过以下方式与我们联系:
在原文文章末尾评论这篇文章
发送电子邮件至 [email protected]
加入我们的 gitter room
发推文给我们 @fullstackreact
REACT.JS DOM 应用 移动 JAVASCRIPT
版权声明 本译文仅用于学习、研究和交流目的,欢迎非商业转载。转载请注明出处、译者和众成翻译的完整链接。
原文链接:全栈React: React 30天


如果有疑问可以直接留言评论,如果觉得对你有帮助,可以小小的赞赏一杯奶茶钱,谢谢!!

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值