资讯专栏INFORMATION COLUMN

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

felix0913 / 2725人阅读

摘要:使用承诺对象使我们有机会将异步操作的最终成功或失败关联到功能无论出于何种原因。例如在上面的示例中函数解析为值在成功完成时并在返回值这是另一个承诺上调用函数依此类推等等。这意味着我们只能返回一个承诺一次。

本文转载自:众成翻译
译者: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构造函数来创建新的承诺 (如上面的示例所示)。它接受一个有两个参数来运行的函数:

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"))

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84683.html

相关文章

  • 全栈ReactReact 30教程索引

    摘要:今天我们将讨论创建组件的最终方案,即无状态函数的纯组件。今天我们正在研究一种处理提出的复杂数据的方法,称为体系结构。第天部署介绍今天,我们将探讨部署我们的应用所涉及的不同部分,以便外界可以使用我们的应用。 本文转载自:众成翻译译者:iOSDevLog链接:http://www.zcfy.cc/article/3758原文:https://www.fullstackreact.com/3...

    appetizerio 评论0 收藏0
  • 全栈React18: Flux 简介

    摘要:在方法中处理数据有三不同的角色派发器储存视图层我们的组件的主要思想是有一个单一源储存他们只能通过触发更新。这些操作负责调用派发器可以订阅更改并相应地更新自己的数据。与不同不使用派发器而是使用纯函数来定义数据变异函数。 本文转载自:众成翻译译者:iOSDevLog链接:http://www.zcfy.cc/article/3812原文:https://www.fullstackreact...

    mtunique 评论0 收藏0
  • 全栈React22: 测试简介

    摘要:我们将讨论三种不同的软件测试范例单元测试功能测试和集成测试。在中单元测试通常不需要浏览器可以快速运行不需要写入断言本身通常是简单而简洁的。集成测试最后我们将研究的最后一种测试是集成测试。 本文转载自:众成翻译译者:iOSDevLog链接:http://www.zcfy.cc/article/3809原文:https://www.fullstackreact.com/30-days-of...

    qc1iu 评论0 收藏0
  • 前端相关汇总

    摘要:简介前端发展迅速,开发者富有的创造力不断的给前端生态注入新生命,各种库框架工程化构建工具层出不穷,眼花缭乱,不盲目追求前沿技术,学习框架和库在满足自己开发需求的基础上,然后最好可以对源码进行调研,了解和深入实现原理,从中可以获得更多的收获随 showImg(https://segmentfault.com/img/remote/1460000016784101?w=936&h=397)...

    BenCHou 评论0 收藏0
  • 前端面试题总结(js、html、小程序、React、ES6、Vue、算法、全栈热门视频资源)

    摘要:并总结经典面试题集各种算法和插件前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快速搭建项目。 本文是关注微信小程序的开发和面试问题,由基础到困难循序渐进,适合面试和开发小程序。并总结vue React html css js 经典面试题 集各种算法和插件、前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快...

    pumpkin9 评论0 收藏0

发表评论

0条评论

felix0913

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<