ES6中Promise使用详解

这次给大家带来ES6中Promise使用详解,ES6中Promise使用的注意事项有哪些,下面就是实战案例,一起来看一下。

当然,这并不代表迸发成了全栈。全栈的技能很集中,绝不仅仅是前端会写一些HTML和一些交互,后台熟悉数据库的增删查改。

想必接触过Node的人都知道,Node是以异步(Async)回调著称的,其异步性提高了程序的执行效率,但同时也减少了程序的可读性。如果我们有几个异步操作,并且后一个操作需要前一个操作返回的数据才能执行,这样按照Node的一般执行规律,要实现有序的异步操作,通常是一层加一层嵌套下去。

为了解决这个问题,ES6提出了Promise的实现。

含义

Promise 对象用于一个异步操作的最终完成(或失败)及其结果值的表示。简单点说,它就是用于处理异步操作的,异步处理成功了就执行成功的操作,异步处理失败了就捕获错误或者停止后续操作。

它的一般表示形式为:

new Promise(  /* executor */  function(resolve, reject) {    if (/* success */) {      // ...执行代码      resolve();    } else { /* fail */      // ...执行代码      reject();    }  });

登录后复制

其中,Promise中的参数executor是一个执行器函数,它有两个参数resolve和reject。它内部通常有一些异步操作,如果异步操作成功,则可以调用resolve()来将该实例的状态置为fulfilled,即已完成的,如果一旦失败,可以调用reject()来将该实例的状态置为rejected,即失败的。

我们可以把Promise对象看成是一条工厂的流水线,对于流水线来说,从它的工作职能上看,它只有三种状态,一个是初始状态(刚开机的时候),一个是加工产品成功,一个是加工产品失败(出现了某些故障)。同样对于Promise对象来说,它也有三种状态:

pending:初始状态,也称为未定状态,就是初始化Promise时,调用executor执行器函数后的状态。

fulfilled:完成状态,意味着异步操作成功。

rejected:失败状态,意味着异步操作失败。

它只有两种状态可以转化,即

操作成功:pending -> fulfilled

操作失败:pending -> rejected

并且这个状态转化是单向的,不可逆转,已经确定的状态(fulfilled/rejected)无法转回初始状态(pending)。

方法

Promise.prototype.then()

Promise对象含有then方法,then()调用后返回一个Promise对象,意味着实例化后的Promise对象可以进行链式调用,而且这个then()方法可以接收两个函数,一个是处理成功后的函数,一个是处理错误结果的函数。

如下:

var promise1 = new Promise(function(resolve, reject) { // 2秒后置为接收状态 setTimeout(function() {  resolve('success'); }, 2000);});promise1.then(function(data) { console.log(data); // success}, function(err) { console.log(err); // 不执行}).then(function(data) { // 上一步的then()方法没有返回值 console.log('链式调用:' + data); // 链式调用:undefined }).then(function(data) { // ....});

登录后复制

在这里我们主要关注promise1.then()方法调用后返回的Promise对象的状态,是pending还是fulfilled,或者是rejected?

返回的这个Promise对象的状态主要是根据promise1.then()方法返回的值,大致分为以下几种情况:

如果then()方法中返回了一个参数值,那么返回的Promise将会变成接收状态。

如果then()方法中抛出了一个异常,那么返回的Promise将会变成拒绝状态。

如果then()方法调用resolve()方法,那么返回的Promise将会变成接收状态。

如果then()方法调用reject()方法,那么返回的Promise将会变成拒绝状态。

如果then()方法返回了一个未知状态(pending)的Promise新实例,那么返回的新Promise就是未知状态。

如果then()方法没有明确指定的resolve(data)/reject(data)/return data时,那么返回的新Promise就是接收状态,可以一层一层地往下传递。

转换实例如下:

var promise2 = new Promise(function(resolve, reject) { // 2秒后置为接收状态 setTimeout(function() {  resolve('success'); }, 2000);});promise2 .then(function(data) {  // 上一个then()调用了resolve,置为fulfilled态  console.log('第一个then');  console.log(data);  return '2'; }) .then(function(data) {  // 此时这里的状态也是fulfilled, 因为上一步返回了2  console.log('第二个then');  console.log(data); // 2  return new Promise(function(resolve, reject) {   reject('把状态置为rejected error'); // 返回一个rejected的Promise实例  }); }, function(err) {  // error }) .then(function(data) {  /* 这里不运行 */  console.log('第三个then');  console.log(data);  // .... }, function(err) {  // error回调  // 此时这里的状态也是fulfilled, 因为上一步使用了reject()来返回值  console.log('出错:' + err); // 出错:把状态置为rejected error }) .then(function(data) {  // 没有明确指定返回值,默认返回fulfilled  console.log('这里是fulfilled态');});

登录后复制

Promise.prototype.catch()

catch()方法和then()方法一样,都会返回一个新的Promise对象,它主要用于捕获异步操作时出现的异常。因此,我们通常省略then()方法的第二个参数,把错误处理控制权转交给其后面的catch()函数,如下:

var promise3 = new Promise(function(resolve, reject) { setTimeout(function() {  reject('reject'); }, 2000);});promise3.then(function(data) { console.log('这里是fulfilled状态'); // 这里不会触发 // ...}).catch(function(err) { // 最后的catch()方法可以捕获在这一条Promise链上的异常 console.log('出错:' + err); // 出错:reject});

登录后复制

Promise.all()

Promise.all()接收一个参数,它必须是可以迭代的,比如数组。

它通常用来处理一些并发的异步操作,即它们的结果互不干扰,但是又需要异步执行。它最终只有两种状态:成功或者失败。

它的状态受参数内各个值的状态影响,即里面状态全部为fulfilled时,它才会变成fulfilled,否则变成rejected。

成功调用后返回一个数组,数组的值是有序的,即按照传入参数的数组的值操作后返回的结果。如下:

// 置为fulfilled状态的情况var arr = [1, 2, 3];var promises = arr.map(function(e) { return new Promise(function(resolve, reject) {  resolve(e * 5); });});Promise.all(promises).then(function(data) {  // 有序输出 console.log(data); // [5, 10, 15] console.log(arr); // [1, 2, 3]});

登录后复制

// 置为rejected状态的情况var arr = [1, 2, 3];var promises2 = arr.map(function(e) { return new Promise(function(resolve, reject) {  if (e === 3) {   reject('rejected');  }  resolve(e * 5); });});Promise.all(promises2).then(function(data) { // 这里不会执行 console.log(data); console.log(arr);}).catch(function(err) { console.log(err); // rejected});

登录后复制

Promise.race()

Promise.race()和Promise.all()类似,都接收一个可以迭代的参数,但是不同之处是Promise.race()的状态变化不是全部受参数内的状态影响,一旦参数内有一个值的状态发生的改变,那么该Promise的状态就是改变的状态。就跟race单词的字面意思一样,谁跑的快谁赢。如下:

var p1 = new Promise(function(resolve, reject) { setTimeout(resolve, 300, 'p1 doned');});var p2 = new Promise(function(resolve, reject) { setTimeout(resolve, 50, 'p2 doned');});var p3 = new Promise(function(resolve, reject) { setTimeout(reject, 100, 'p3 rejected');});Promise.race([p1, p2, p3]).then(function(data) { // 显然p2更快,所以状态变成了fulfilled // 如果p3更快,那么状态就会变成rejected console.log(data); // p2 doned}).catch(function(err) { console.log(err); // 不执行});

登录后复制

Promise.resolve()

Promise.resolve()接受一个参数值,可以是普通的值,具有then()方法的对象和Promise实例。正常情况下,它返回一个Promise对象,状态为fulfilled。但是,当解析时发生错误时,返回的Promise对象将会置为rejected态。如下:

// 参数为普通值var p4 = Promise.resolve(5);p4.then(function(data) { console.log(data); // 5});// 参数为含有then()方法的对象var obj = { then: function() {  console.log('obj 里面的then()方法'); }};var p5 = Promise.resolve(obj);p5.then(function(data) { // 这里的值时obj方法里面返回的值 console.log(data); // obj 里面的then()方法});// 参数为Promise实例var p6 = Promise.resolve(7);var p7 = Promise.resolve(p6);p7.then(function(data) { // 这里的值时Promise实例返回的值 console.log(data); // 7});// 参数为Promise实例,但参数是rejected态var p8 = Promise.reject(8);var p9 = Promise.resolve(p8);p9.then(function(data) { // 这里的值时Promise实例返回的值 console.log('fulfilled:'+ data); // 不执行}).catch(function(err) { console.log('rejected:' + err); // rejected: 8});

登录后复制

Promise.reject()

Promise.reject()和Promise.resolve()正好相反,它接收一个参数值reason,即发生异常的原因。此时返回的Promise对象将会置为rejected态。如下:

var p10 = Promise.reject('手动拒绝');p10.then(function(data) { console.log(data); // 这里不会执行,因为是rejected态}).catch(function(err) { console.log(err); // 手动拒绝}).then(function(data) { // 不受上一级影响 console.log('状态:fulfilled'); // 状态:fulfilled});

登录后复制

总之,除非Promise.then()方法内部抛出异常或者是明确置为rejected态,否则它返回的Promise的状态都是fulfilled态,即完成态,并且它的状态不受它的上一级的状态的影响。

总结

大概常用的方法就写那么多,剩下的看自己实际需要再去了解。

解决Node回调地狱的不止有Promise,还有Generator和ES7提出的Async实现。

相信看了本文案例你已经掌握了方法,更多精彩请关注【创想鸟】其它相关文章!

推荐阅读:

怎样使用Vue实现树形视图数据

如何使用JS求得数组的最小公倍数和最大公约数

以上就是ES6中Promise使用详解的详细内容,更多请关注【创想鸟】其它相关文章!

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

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2753076.html

(0)
上一篇 2025年3月8日 06:33:06
下一篇 2025年3月1日 06:13:45

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • Vue数据响应使用步骤详解

    这次给大家带来Vue数据响应使用步骤详解,使用Vue数据响应的注意事项有哪些,下面就是实战案例,一起来看一下。 前言 Vue的数据响应主要是依赖了Object.defineProperty(),那么整个过程是怎么样的呢?以我们自己的想法来走…

    2025年3月8日 编程技术
    200
  • JS内this指向使用实例详解

    这次给大家带来JS内this指向使用实例详解,JS内this指向使用的注意事项有哪些,下面就是实战案例,一起来看一下。 在具体的实际应用中,this 的指向无法在函数定义时确定,而是在函数执行的时候才确定的,根据执行时的环境大致可以分为以下…

    编程技术 2025年3月8日
    200
  • es6中class特性使用案例详解

    这次给大家带来es6中class特性使用案例详解,es6中class特性使用的注意事项有哪些,下面就是实战案例,一起来看一下。 javaScript 语言中,生成实例对象的传统方法是通过构造函数,与传统的面向对象语言(比如 C++ 和 Ja…

    编程技术 2025年3月8日
    200
  • JS加载方式使用汇总

    这次给大家带来JS加载方式使用汇总,JS加载方式使用的注意事项有哪些,下面就是实战案例,一起来看一下。 一:同步加载 我们平时使用的最多的一种方式。 同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止后续的解析,只有当当前加载完成,才能进…

    编程技术 2025年3月8日
    200
  • 如何使用redux-saga,使用redux-saga又有哪些方法和技巧?

    这篇文章主要介绍了redux-saga 初识和使,现在分享给大家,也给大家做个参考。 redux-saga 是一个管理 Redux 应用异步操作的中间件,功能类似redux-thunk + async/await, 它通过创建 Sagas …

    编程技术 2025年3月8日
    200
  • JS反射与依赖注入使用案例分析

    这次给大家带来JS反射与依赖注入使用案例分析,JS反射与依赖注入使用的注意事项有哪些,下面就是实战案例,一起来看一下。 对于javascript中的反射的理解,一直都是认为,利用数组对回调函数进行保存,之后在适当的时刻利用call或是app…

    编程技术 2025年3月8日
    200
  • 在vue项目中,使用axios跨域处理

    下面我就为大家分享一篇在vue项目中,使用axios跨域处理,具有很好的参考价值,希望对大家有所帮助。 跨域,一个很是让人尴尬的问题,有些人可以在后台中设置请求头,但是很多前端并不具备后台的知识,并无法自己独立的搭建一个服务器,所以就变成了…

    2025年3月8日
    200
  • 关于在使用vue.js标签属性中插入变量参数的方法(详细教程)

    这篇文章主要介绍了vue.js在标签属性中插入变量参数的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下 html的标签的属性,比如id、class、href需要动态传递参数,拼接字符串,查了一些资料,并没有找到合适的解决方法,琢磨了…

    2025年3月8日
    200
  • JS获取月具体天数步骤详解

    这次给大家带来JS获取月具体天数步骤详解,JS获取月具体天数的注意事项有哪些,下面就是实战案例,一起来看一下。 Javascript里面的new  Date(“xxxx/xx/xx”)这个日期的构造方法有一个妙处,当…

    编程技术 2025年3月8日
    200
  • node跨域使用express+http-proxy-middleware步骤详解

    这次给大家带来node跨域使用express+http-proxy-middleware步骤详解,node跨域使用express+http-proxy-middleware的注意事项有哪些,下面就是实战案例,一起来看一下。 为什么要使用no…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论