热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

20170702异步编程之Promise

1.Promise的含义Promise是异步编程的一种解决方案Promise实例代表一个异步操作,从它可以获取异步操作的消息Promise实例有三种状态:

1.Promise的含义

  • Promise是异步编程的一种解决方案

  • Promise实例代表一个异步操作,从它可以获取异步操作的消息

  • Promise实例有三种状态:

    • Pending:进行中

    • Resolved:已完成

    • Rejected:已失败

  • Promise实例的状态只能由 Pending->Resolved, Pending->Rejected。一旦Promise实例的状态发生改变,就不会再发生变化,任何时候都可以得到这个结果

  • 为什么要使用Promise:通过Promise,可以将一步操作以同步操作的流程表达出来,可以避免层层嵌套的回调函数(回调地域),并且Promise提供了统一的接口,使得控制异步操作更加容易

2.Promise构造函数

Promise是一个构造函数,用来生成Promise实例

var promise = new Promise(function(resolve, reject)){// ... do somethingif (/*异步操作成果*/) {resolve(value)} else { /*异步操作失败*/reject(error)}
}

  • Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由 Javascript 引擎提供,不用自己部署。

  • resolve函数的作用是,将Promise实例的状态从“未完成”变为“成功”(即从 Pending 变为 Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去

  • reject函数的作用是,将Promise实例的状态从“未完成”变为“失败”(即从 Pending 变为 Rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去**

Promise.prototype.then()

Promise实例生成以后,可以用then方法分别指定Resolved状态和Reject状态的回调函数。

var promise = new Promise(function(resolve, reject)){// ... do somethingif (/*异步操作成果*/) {resolve(value)} else { /*异步操作失败*/reject(error)}
}
promise.then(function(value) {// success
}, function(error) {// failure
});

  • then方法可以接受两个回调函数作为参数。第一个回调函数是Promise的状态变为Resolved时调用,第二个回调函数是Promise实例的状态变为Rejected时调用。其中,第二个函数是可选的,不一定要提供。

  • 这两个函数都接受Promise实例传出的值作为参数。(简单地说就是:上面的promise对象在处理异步操作的过程中,如果调用了resolve方法,则会将resolve的参数传递给then方法的第一个函数,如果调用了reject方法,这会将reject的参数传递给then方法的第二个函数)

clipboard.png

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例),因此可以采用链式写法,即then方法后面在调用另一个then方法

clipboard.png

上面的代码使用then方法,依次指定了两个回调函数。第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。(实际上是第一个then方法返回了一个Promise实例,在该实例中调用了resolve方法,而json.post则是作为resolve的参数)


clipboard.png

上面代码中,第一个then方法指定的回调函数,返回的是另一个Promise实例,则第一个then方法会直接将该Promise实例返回

Promise.prototype.catch()

该方法是.then(undefined, onRejected)的别名,用于指定发生错误时的回调函数。

promise.then(function(data) {console.log('success');
}).catch(function(error) {console.log('error', error);
});

promise对象的错误,会一直向后传递,直到被捕获。即错误总会被下一个catch所捕获。then方法指定的回调函数,若抛出错误,也会被下一个catch捕获。catch中也能抛错,则需要后面的catch来捕获。

sendRequest('test.html').then(function(data1) {//do something
}).then(function (data2) {//do something
}).catch(function (error) {//处理前面三个Promise产生的错误
});

Promise.all()

该方法用于将多个Promise实例,包装成一个新的Promise实例

// p1,p2,p3都是promise实例
var p = Promise.all([p1, p2, p3]);

新的Promise实例的状态由三个promise实例共同决定

  • 当三个promise实例的状态都变为fulfilled,p的状态才会变为fulfilled,并将三个promise返回的结果,按照参数顺序存入数组,传给p的回调函数

  • 当p1, p2, p3其中之一状态变为rejected,p的状态也会变为rejected,并把第一个被reject的promise的返回值,传给p的回调函数

Promise..race()

该方法用于将多个Promise实例,包装成一个新的Promise实例

// p1,p2,p3都是promise实例
var p = Promise.race([p1, p2, p3]);

新的Promise实例的状态由三个promise实例共同决定

  • 当p1, p2, p3其中之一状态发生改变(变为fulfilled或者rejected),p的状态也会随之改变,并把第一个改变状态的promise的返回值,传给p的回调函数

Promise.resolve()

Promise.resolve方法的参数分为四种情况

  • 参数是一个Promise实例

如果参数是Promise实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

  • 参数是一个thenable对象

let thenable = {then: function(resolve, reject) {resolve(42);}
};let p1 = Promise.resolve(thenable);
p1.then(function(value) {console.log(value); // 42
});

Promise.resolve方法会将这个对象转为Promise对象,然后就立即执行thenable对象的then方法。

  • 参数不是具有then方法的对象,或根本就不是对象

如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的Promise对象,状态为Resolved。

Promise.resolve('Success');/*******等同于*******/
new Promise(function (resolve) {resolve('Success');
});

  • 不带任何参数

直接返回一个Resolved状态的Promise对象。

Promise.resolve('Success');/*******等同于*******/
new Promise(function (resolve) {resolve();
});

Promise.reject()

Promise.reject(new Error('error'));/*******等同于*******/
new Promise(function (resolve, reject) {reject(new Error('error'));
});

这段代码会让这个Promise对象立即进入rejected状态,并将错误对象传递给then指定的onRejected回调函数。

参考资料

ECMAScript 6 入门




推荐阅读
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 在编写业务代码时,常常会遇到复杂的业务逻辑导致代码冗长混乱的情况。为了解决这个问题,可以利用中间件模式来简化代码逻辑。中间件模式可以帮助我们更好地设计架构和代码,提高代码质量。本文介绍了中间件模式的基本概念和用法。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 使用正则表达式爬取36Kr网站首页新闻的操作步骤和代码示例
    本文介绍了使用正则表达式来爬取36Kr网站首页所有新闻的操作步骤和代码示例。通过访问网站、查找关键词、编写代码等步骤,可以获取到网站首页的新闻数据。代码示例使用Python编写,并使用正则表达式来提取所需的数据。详细的操作步骤和代码示例可以参考本文内容。 ... [详细]
  • 在springmvc框架中,前台ajax调用方法,对图片批量下载,如何弹出提示保存位置选框?Controller方法 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • python限制递归次数(python最大公约数递归)
    本文目录一览:1、python为什么要进行递归限制 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
author-avatar
agree_6398026768
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有