【全栈React】第15天: Promise简介

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

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

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

Promise

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

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

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

例如,考虑下面的同步代码,我们在 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');
});

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

进入Promise

使用承诺,另一方面帮助我们避免了很多这种复杂性 (虽然不是一个银弹解决方案,参考《人月神话》)。以前的代码,这可以被称为意大利面条代码可以变成一个更整洁,更同步的前瞻版本:

function getCurrentTime(onSuccess,onFail) {
  // 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() 函数调用,无论返回值是Promise本身。例如,在上面的示例中,getCurrentTime() 函数解析为currentTime() 值 (在成功完成时),并在返回值 (这是另一个承诺) 上调用then() 函数,依此类推等等。

要捕获在承诺链中任何地方发生的错误,我们可以使用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))

单使用Guarantee

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

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

创建一个Promise

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

从上面回顾我们的函数,我们可以看到,如果请求成功,我们调用 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'))

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom