Promise初步详解(resolve,reject,catch)

一:何为Promise?

为了直观一点,首先我们采用console.dir(Promise)看一下它的结构组成。

从上面的图片中我们可以到,Promise其实是一个构造函数,它有resolve,reject,race等静态方法;它的原型(prototype)上有then,catch方法,因此只要作为Promise的实例,都可以共享并调用Promise.prototype上面的方法(then,catch),接下来我们试着使用一下Promise。

二:Promise的使用


首先我们来看一下Promise的使用语法:

new Promise(function(resolve,reject){}/*excutor*/);

在实例化Promise时需要传入一个函数excutor作为参数,并且在Promise构造函数执行时同步执行。废话不多说,先看一个简单的实例:

   var p = new Promise(function(resolve,reject){var timer = setTimeout(function(){console.log('执行操作1');},1000);});

我们可以看到1s后在控制台输出相应的结果,这就说明在实例化过程中,作为参数的excutor函数也会执行。

从上面的实例中我们看到,excutor函数还有两个参数resolve和reject,其实这两个参数也是函数,在excutor执行时被调用,下面我们具体来谈谈resolve和reject的用法。

三:resolve和reject的具体用法

1.先来说说resolve的用法

首先我们来看看Promise的几种状态:

pending: 初始状态,成功或失败状态。

fulfilled: 意味着操作成功完成。

rejected: 意味着操作失败。

当我们在excutor函数中调用resolve方法时,Promise的状态就变成fulfilled,即操作成功状态,还记得上面Promise.prototype上面的then和catch方法吗?当Promise状态为fullfilled状态时执行then方法里的操作,注意了,then方法里面有两个参数onfulfilled(Promise为fulfilled状态时执行) 和onrejected(Promise为rejected状态时执行),步骤如下:

1.实例化Promise(new Promise(function(resolve,reject)))

2.用Promise的实例调用then方法。

具体来看下面的例子:

    var p = new Promise(function (resolve, reject) {var timer = setTimeout(function () {console.log('执行操作1');resolve('这是数据1');}, 1000);});p.then(function (data) {console.log(data);console.log('这是成功操作');});

简单的理解就是调用resolve方法,Promise变为操作成功状态(fulfilled),执行then方法里面onfulfilled里的操作。其实then里面的函数就是我们平时所说的回调函数,只不过在这里只是把它分离出来而已。我们可以看到控制台上的输出结果如下所示:

2.reject的用法

看了上面的实例,我相信应该也很容易理解reject方法了,就是调用reject方法后,Promise状态变为rejected,即操作失败状态,此时执行then方法里面onrejected操作,上面我们提到了then方法有两个参数,一种是Promise状态为fulfilled时执行(onfullfilled),一种是Promise状态为rejected时执行(onrejected),其实就是类似于jquery里的hover方法里面的两个参数一样,来看看下面的例子:

    var p = new Promise(function (resolve, reject) {var flag = false;if(flag){resolve('这是数据2');}else{reject('这是数据2');}});p.then(function(data){//状态为fulfilled时执行console.log(data);console.log('这是成功操作');},function(reason){ //状态为rejected时执行console.log(reason);console.log('这是失败的操作');});

 我们可以看到输出结果:

三:catch方法

我们注意到除了then方法外,Promise原型上还有另外一个叫catch的方法,那么这个方法的作用是什么呢?其实跟then方法中的第二个参数一样,就是在Promise状态为rejected时执行,then方法捕捉到Promise的状态为rejected,就执行catch方法里面的操作,下面用catch方法改写上面reject用法里面的例子,如下所示:

  var p = new Promise(function (resolve, reject) {var flag = false;if(flag){resolve('这是数据2');}else{reject('这是数据2');}});p.then(function(data){console.log(data);console.log('这是成功操作');}).catch(function(reason){console.log(reason);console.log('这是失败的操作');});

执行结果和上面reject用法的例子一样。

四.为何用Promise

首先我们来看这样一个例子,取4个定时器,设置延迟时间都为1s,然后每隔1s依次在控制台输出‘我’‘爱’‘米’‘饭’的字样。代码如下:

      setTimeout(function () {console.log('我');setTimeout(function () {console.log('爱');setTimeout(function () {console.log('米');setTimeout(function () {console.log('饭');}, 1000);}, 1000);}, 1000);}, 1000);

发现什么问题没有?是不是有点感觉回调函数的嵌套有点多,如果有更多的回调函数呢?是不是使代码的可读性和可维护性都大大降低了呢(回调地狱?),这时如果我们使用Promise去实现这个效果,虽然可能代码不会减少,甚至更多,但是却大大增强了其可读性和可维护性。具体看下面例子:

            function getStr1() {return new Promise(function (resolve, reject) {setTimeout(function () {resolve('我');}, 1000);});}function getStr2() {return new Promise(function (resolve, reject) {setTimeout(function () {resolve('爱');}, 1000);});}function getStr3() {return new Promise(function (resolve, reject) {setTimeout(function () {resolve('米');}, 1000);});}function getStr4() {return new Promise(function (resolve, reject) {setTimeout(function () {resolve('饭');}, 1000);});}getStr1().then(function (data) {console.log(data);return getStr2();}).then(function (data) {console.log(data);return getStr3();}).then(function (data) {console.log(data);return getStr4();}).then(function (data) {console.log(data);})

执行效果跟上面一样,在这个例子中,将得到Promise实例的过程封装成一个函数(getStr1,getStr2,getStr3,getStr4)并返回一个Promise实例,再用实例去调用相应的then方法,在每个then方法中通过return得到下一级的Promise实例,比如在第一个Promise实例(getStr1())then方法中,通过return返回下一个Promise对象(getStr2()),然后再去调用then方法执行里面的操作,再返回下一个Promise对象(这里是getStr3()),这样一级一级下去实现了链式调用,虽然代码量增加了,但比起前面的层层嵌套,显然这种方式使得代码更易读更易维护。

本文对Promise的介绍就到这里,欢迎大家指正里面的错误和不准确的地方。

转载于:https://www.cnblogs.com/homeStrong/p/8231889.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/414954.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

session 的 源码

session 的 源码 1.session 和 cookie 的 区别: 答: cookie 它是保存在浏览器的键值对。 session 它是保存在服务端的键值对。 它 依赖cookie 存在。 流程: 一个服务端, 一个客户端第一次来 服务端 去 客户端 发来的请求里的…

前端学习(2682):重读vue电商网站3之登录页面总结el-form 组件问题

el-form 组件默认是 content-box,我们设置其如下属性时,就会出现长度比我们想象中长一点的情况。 .login_form {position: absolute;bottom: 60px;width: 100%;padding: 0 20px; //多加一行box-sizing: border-box; } 运行结果

Android 统一View样式,textview样式

xmlns:tools"http://schemas.android.com/tools" android:text"提示" 1、在values文件夹下的styles文件里面创建textview样式——android:style/Widget.TextView可以替换为其他view,如&#xff1a;button,CheckBox。。。。。 <style name"mytextst…

前端学习(2683):重读vue电商网站4之登录页面总结使用 iconfont 给输入框添加图标

在 main.js 中导入字体图标 然后在 el-input 组件中通过 prefix-icon 进行相关图标引用 最终效果图如下&#xff1a;

Highcharts隐藏网格线

原始效果 加上代码 yAxis: {gridLineWidth: 0,minorGridLineWidth: 0}

前端学习(2684):重读vue电商网站5之登录页面总结如何进行表单验证

Form 组件提供了表单验证的功能&#xff0c;只需要通过 rules 属性传入约定的验证规则&#xff0c;并将 Form-Item 的 prop 属性设置为需校验的字段名即可。 通过 rules 属性传入约定的验证规则 将Form-Item 的 prop 属性设置为需校验的字段名

Android 贴纸样式标签

demo链接&#xff1a;https://download.csdn.net/download/meixi_android/10802704 样式效果 实现方法&#xff1a; 1、自定义标签类 public class LabelImageView extends ImageView {LabelViewHelper utils;public LabelImageView(Context context) {this(context, null);…

Java研发工程师面试题(1)

Java研发工程师面试题(1) 基础题 一、String,StringBuffer, StringBuilder 的区别是什么&#xff1f;String为什么是不可变的&#xff1f;1. String是字符串常量&#xff0c;StringBuffer和StringBuilder是字符串变量。StringBuffer是线程安全的&#xff0c;StringBuilder是非线…

前端学习(2685):重读vue电商网站6之如何重置表单

element-ui 对表单提供了如下方法 resetFields&#xff0c;我们只需要获取表单对象数据即可重置我们的表单。 获取表单对象方式如下&#xff1a; 直接在表单处添加 ref属性&#xff0c;如下 loginFormRef&#xff0c;此引用即为我们表单实例。 然后&#xff0c;在我们重置按钮…

android Camera 设置焦距

1、添加Camera权限 2、判断是否支持变焦 public boolean isSupportZoom(){boolean isSuppport true;if (mCamera.getParameters().isSmoothZoomSupported()){isSuppport false;}return isSuppport;} 3、修改焦距 public void setZoom(){if (mIsSupportZoom){try{Parameters …

v-contextmenu的使用(右键菜单)

先来个自己改写的图&#xff1a; 代码&#xff1a; 结构&#xff1a;<div class"wrap" v-contextmenu:contextmenu><v-contextmenu ref"contextmenu"> <v-contextmenu-item ><i class"fa fa-search"></i>上插入&l…

前端学习(2686):重读vue电商网站7之登录预校验

在我们点击登录按钮&#xff0c;不应该直接发起网络请求&#xff0c;而是应该对表单进行预校验&#xff0c;检验成功才会发送请求。 拿到表单引用对象&#xff0c;即可进行对表单的校验。 首先&#xff0c;给登录按钮通过 click 来绑定一个事件 下一步&#xff0c;在 methods …

Android 循环滚动控件ViewFlipper,可实现跑马灯或轮播图效果

ViewFlipper——Android循环滚动控件 1、效果如下&#xff1a; 2、实现方法 &#xff08;1&#xff09;创建进出动画 上下滚动动画 y_in.xml <?xml version"1.0" encoding"utf-8"?> <set xmlns:android"http://schemas.android.com/a…

vue js table colspan rowspan

需求&#xff0c;要写一个菜单权限表。需要做到单元格合并&#xff0c;本来用的antd-vue的表格&#xff0c;然后构造customRender,总感觉有点本末倒置&#xff0c;其实自己实现&#xff0c;更快&#xff0c;而且想改哪里&#xff0c;改哪里。下面是写这个功能前的测试demo。 效…

前端学习(2687):重读vue电商网站8之设置弹框提示组件

首先&#xff0c;在 element.js 中导入弹框提示组件&#xff0c;但是它的配置与其它组件不一样&#xff0c;它需要进行全局挂载。 全局导入后&#xff0c;我们就可以在我们的登录组件 login.vue 中通过 this来访问弹框提示组件了。 测试一下&#xff0c;输入 admin 和 123456&a…

table 权限 展示页面

上篇文件介绍了基本的colspan和rowspan&#xff0c;这篇贴上一个学习代码&#xff0c;供以后修改。 效果如下&#xff1a;&#xff08;这个demo v-if 和 v-for 混用了&#xff0c;这个不好&#xff09; <template><div class"rbac-table"><div clas…

vue 公用组件开发 确认框confirm

文件目录&#xff1a; github地址&#xff1a;https://github.com/xingkongwuyu/vue-spa-experience/tree/master/src/components 最终的效果&#xff1a; 组件的源码解析&#xff1a; confirm &#xff1a; confirm的框架 ./index.js import confirmBox from ./src/index; ex…

前端学习(2688):重读vue电商网站9之el-menu 默认会有一个 border-right

这样会导致我们的菜单栏右边会有一个若隐若现的线条凸起 解决办法如下&#xff0c;直接将 el-menu 的border-right 设置为 none 即可。

Android studio 导入module方法

添加module方法步骤&#xff1a; &#xff08;1&#xff09;File----->New------>Import Module找到下载的citypicker文件&#xff0c;点击OK&#xff0c;点击Finish &#xff08;2&#xff09;app的build.gradle下的dependencies下添加 compile project(:citypicker)如…