前端

当前位置:新萄京娱乐 > 前端 > 前端基础进阶(十三):透彻掌握Promise的使用读

前端基础进阶(十三):透彻掌握Promise的使用读

来源:未知 作者:新萄京娱乐 时间:2019-03-27 07:03

  Promise的重要性我认为我没有必要多讲,概括起来说就是必须得掌握,而且还要掌握透彻。这篇文章的开头,主要跟大家分析一下,为什么会有Promise出现。

  在实际的使用当中,有非常多的应用场景我们不能立即知道应该如何继续往下执行。最重要也是最主要的一个场景就是ajax请求。通俗来说,由于网速的不同,可能你得到返回值的时间也是不同的,这个时候我们就需要等待,结果出来了之后才知道怎么样继续下去。

  在ajax的原生实现中,利用了onreadystatechange事件,当该事件触发并且符合一定条件时,才能拿到我们想要的数据,之后我们才能开始处理数据。

  这样做看上去并没有什么麻烦,但是如果这个时候,我们还需要做另外一个ajax请求,这个新的ajax请求的其中一个参数,得从上一个ajax请求中获取,这个时候我们就不得不如下这样做:

  当出现第三个ajax(甚至更多)仍然依赖上一个请求的时候,我们的代码就变成了一场灾难。这场灾难,往往也被称为回调地狱。

  当然,除了回调地狱之外,还有一个非常重要的需求:为了我们的代码更加具有可读性和可维护性,我们需要将数据请求与数据处理明确的区分开来。上面的写法,是完全没有区分开,当数据变得复杂时,也许我们自己都无法轻松维护自己的代码了。这也是模块化过程中,必须要掌握的一个重要技能,请一定重视。

  从前面几篇文中的知识我们可以知道,当我们想要确保某代码在谁谁之后执行时,我们可以利用函数调用栈,将我们想要执行的代码放入回调函数中。

  确保我们想要的代码压后执行,除了利用函数调用栈的执行顺序之外,我们还可以利用上一篇文章所述的队列机制。

  如果浏览器已经支持了原生的Promise对象,那么我们就知道,浏览器的js引擎里已经有了Promise队列,这样就可以利用Promise将任务放在它的队列中去。

  为了更好的往下扩展Promise的应用,这里需要先跟大家介绍一下Promsie的基础知识。

  这三种状态不受外界影响,而且状态只能从pending改变为resolved或者rejected,并且不可逆。在Promise对象的构造函数中,将一个函数作为第一个参数。而这个函数,就是用来处理Promise的状态变化。

  二、 Promise对象中的then方法,可以接收构造函数中处理的状态变化,并分别对应执行。then方法有2个参数,第一个函数接收resolved状态的执行,第二个参数接收reject状态的执行。

  then方法的执行结果也会返回一个Promise对象。因此我们可以进行then的链式执行,这也是解决回调地狱的主要方式。

  OK,了解了这些基础知识之后,我们再回过头,利用Promise的知识,对最开始的ajax的例子进行一个简单的封装。看看会是什么样子。

  为了健壮性,处理了很多可能出现的异常,总之,就是正确的返回结果,就resolve一下,错误的返回结果,就reject一下。并且利用上面的参数传递的方式,将正确结果或者错误信息通过他们的参数传递出来。

  现在所有的库几乎都将ajax请求利用Promise进行了封装,因此我们在使用jQuery等库中的ajax请求时,都可以利用Promise来让我们的代码更加优雅和简单。这也是Promise最常用的一个场景,因此我们一定要非常非常熟悉它,这样才能在应用的时候更加灵活。

  当有一个ajax请求,它的参数需要另外2个甚至更多请求都有返回结果之后才能确定,那么这个时候,就需要用到Promise.all来帮助我们应对这个场景。

  Promise.all接收一个Promise对象组成的数组作为参数,当这个数组所有的Promise对象状态都变成resolved或者rejected的时候,它才会去调用then方法。

  与Promise.all相似的是,Promise.race都是以一个Promise对象组成的数组作为参数,不同的是,只要当数组中的其中一个Promsie状态变成resolved或者rejected时,就可以调用.then方法了。而传递给then方法的值也会有所不同,大家可以再浏览器中运行下面的例子与上面的例子进行对比。

  嗯,我所知道的,关于Promise的基础知识就这些了,如果还有别的,欢迎大家补充。

  那么接下来,我们要结合三个不同的应用场景来让大家感受一下Promise在模块系统中如何使用。

  这里选择requirejs是因为学习成本最低,能够快速上手进行简单的运用。接下来的这些例子,会涉及到很多其他的知识,因此如果想要彻底掌握,一定要动手实践,自己试着完成一遍。

  我在github上创建了对应的项目,大家可以直接clone下来进行学习。这样学习效果会更好。

  首先为了能够让require起作用,我们需要在html中引入require.js,写法如下:

  在入口的index.js中,我们可以对常用的模块进行映射配置,这样在引入时就可以少写一些代码。

  OK,了解上面这些,应付基础的使用已经没有问题了。我们接下来重点总结第一个常用的应用场景:ajax。

  关于ajax的简单使用和简单封装,我们在上面都已经讲过了,这里就不再多说,直接使用jquery封装好的方法即可。而我们需要处理的问题在于,如何有效的将ajax的数据请求和数据处理分别放在不同的模块中进行管理,这样做的主要目的在于降低后期维护成本,便于管理。

  在实际开发中,url并不是直接通过字符串就能直接确认的,某些url还需要通过参数拼接等,这个时候需要我们灵活处理。

  在这个模块中,我们还可以对拿到的数据进行一些你需要的过滤处理,确保最终返回给下一个模块的数据是能够直接使用的。

  这就是我所了解的处理ajax的比较好的一个方式,如果你有其他更好的方式也欢迎分享。

  在一些实际应用中,常常会有一些图片需要放置在某一个块中,比如头像,比如某些图片列表。可是源图片的尺寸可能很难保证长宽比例都是一致的,如果我们直接给图片设定宽高,就有可能导致图片变形。变形之后高大上的页面就直接垮掉了。

  因此为了解决这个问题,我们需要一个定制的image组件来解决这个问题。我们期望图片能够根据自己的宽高比,合理的缩放,保证在这个块中不变形的情况下尽可能的显示更多的内容。

  每一张图片都有一个包裹的div,这些div的宽高,就是我们期望图片能保持的宽高。

  我分别定义了aspectFill-x与aspectFill-y,通过判断不同的宽高比,来决定将他们中的其中一个加入到img标签的class中去即可。

  获取图片的原始宽高,需要等到图片加载完毕之后才能获取。而当图片已经存在缓存时,则有一个compete属性变成true。那么我们就可以根据这些基础知识,定义一个模块来处理这件事情。

  因此自己专门定义一个常用的弹窗就变得非常有必要,这对于我们开发效率的提高非常有帮助。当然,我这里只是简单的写了一个简陋的,仅供参考。

  我们期望的是利用Promise,当我们点击确认时,状态变成resolved,点击取消时,状态变成rejected。这样也方便将弹窗生成与后续的操作处理区分开来。

  先定义一个Dialog模块。使用的是最简单的方式定义,应该不会有什么理解上的困难。主要提供了show和hide2个方法,用于展示和隐藏。

  这三种场景就介绍完了,主要是需要大家通过源码来慢慢理解和揣摩。真正掌握之后,相信大家对于Promise在另外的场景中的使用也会变得得心应手。

  最后总结一下,这篇文章,涉及到的东西,有点多。大概包括Promise基础知识,ajax基础知识,如何利用Promise封装ajax,如何使用require模块系统,如何在模块中使用Promise,并且对应的三个应用场景又各自有许多需要了解的知识,因此对于基础稍差的朋友来说,理解透彻了肯定会有一个比较大的进步。当然也会花费你更多的时间。

  另外在我们的工作中还有一件非常重要的事情是需要我们持续去做的。那就是将常用的场景封装成为可以共用的模块,等到下次使用时,就可以直接拿来使用而节省非常多的开发时间。比如我这里对于img的处理,对于弹窗的处理,都是可以扩展成为一个通用的模块的。慢慢积累多了,你的开发效率就可以得到明显的提高,这些积累,也将会变成你的优势所在。

  后续的文章我会分享如何利用react与es6模块系统封装的共用组件,大家也可以学习了之后,根据自己的需求,封装最适合你自己的一套组件。

  最后,最近问我怎么学习的人越来越多,我真的有点回答不过来了,我想把我这些文章里的知识都掌握了,应付毕业之后的第一份工作应该不是什么问题的吧?而且为了你们能够掌握Promise的使用,我还专门给读者老爷们创建了一个项目,列举了整整三个实例,还有源代码供你们学习,我学Promise的时候,找好久都没找到一个稍微接近实际应用的案例,学了好久才知道怎么使用,效率之低可想而知。所以静下心来慢慢学习吧,花点时间是值得的 ~ ~ 。

  00、前言Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(...

  Promiese 简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,语法上说,Promiese是一个对象,从它可以获取异步操作的消息。Promise提供统一的API,各种异步操作都可以用同样的方法进行处理。 Promise对象有以下两个特点。...

  Promise的含义:   Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。     所谓Promise,简单说就是一个容器,里面保存着...

  Promise的含义 Promise ,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。Promise提供统一的API,各种异步操作都可以用同样的方法进行处理。Promise...

  第六重天的主题:觉察烂故事 某某人,根据你的自我定义,你觉得怎样的自己才是值得被爱的?为什么? 根据我的自我定义,我觉得有足够的耐心的我才是值得被爱的,自己性格急,往往耐心不够 2. 某某人,你觉得这个不值得被爱的自己,人生中活该如何遭罪? 人生中有时很遭罪,容易着急上火,...

  美食,亘古不变的全民话题。正所谓,民以食为天,美食也承载着国人对于“吃”的特殊情感眷恋。往细腻了说,美食也是家人,朋友,以及恋人的一种情感载体。想象一下,约三五好友,品一杯浊酒。皓月当空,配几味得体小菜。伴清风徐徐,哪怕说些痴人妄语,岂不快哉? 欸,那今天最了爷就带大家盘点...

  JavaScript 中的 this 经常会表现得让人抓摸不透,甚至让新手感到疑惑不解。 有些文章为了讲解 this,甚至有时会将它和其他概念混在一起讲解,但这只会让人更加疑惑,最后彻底迷失在这些概念中。 本文主要目标就是剔除这些概念的混淆,从本质上看清楚 this。在理解...

本文由新萄京娱乐发布,转载请注明出处:前端基础进阶(十三):透彻掌握Promise的使用读