Promise 的定义

Pormise是JS的异步编程的一种解决方案,在ES6将其写进了语言标准,提供了原生的Promise对象。

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

Promise有下面两个特点:

  1. 对象的状态不受外界影响。有三种状态:padding(进行中)、fulfilled(成功)、rejected(失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

  2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。三个状态只有从padding到fulfilled或者从padding到rejected。状态只有从padding改变到fulfilled或者refected,两种改变。

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

Promise存在的缺点

  1. 无法取消Promise,一旦新建它就会立即执行,无法中途取消。

  2. 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

  3. 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

Promise基本用法

  1. const promise = new Promise((resolve, reject) => {
  2. let status = true;
  3. if (status) {
  4. resolve('操作成功!');
  5. } else {
  6. reject('操作失败!');
  7. }
  8. });
  9.  
  10. promise.then(res => {
  11. console.log('成功结果:' + res);
  12. }, error => {
  13. console.log('失败结果:' + error);
  14.  
  15. });

ES6中,Promise对象是一个构造函数,用来生成Promise实例。Promise构造函数接受一个函数作为参数,接受两个参数,分别是resolve和reject两个函数。

其中,resolve函数作用是将Promise的状态从padding改变成fufilled;而reject函数作用是将Promise的状态从padding改变成rejected。

在Promise实例生产后,可以用then方法分别指定了fufilled状态和rejected状态的回调函数。

其中then方法接受两个参数,第一个回调函数是状态改变fufilled时调用的,第二个回调函数是状态改变refected时调用的。第二个参数是可选的,不一定要提供。

  1. const promise = new Promise((resolve, reject) => {
  2. console.log('new Promise()');
  3. resolve();
  4. });
  5.  
  6. promise.then(() => {
  7. console.log('resolve()');
  8. });
  9.  
  10. console.log('End');

上面是一个Promise对的简单写法,我们看下上面的例子是如何输出的。

  1. // 执行结果
  1. new Promise()
  2. End
  3. resolve()

在上面的例子中因为Promise对象是同步的所以先输出,then方法是异步的所以后输出。

Promise的语法糖then

Promise实例具有then方法,then方法是定义在原型对象Promise.prototype上的。它的作用前面说过,第一个回调函数是状态改变fufilled时调用的,第二个回调函数(可选)是状态改变rejected时调用的。

  1. new Promise((resolve, reject) => {
  2. resolve('王小端Coder');
  3. }).then(res => {
  4. console.log(res); // 王小端Coder
  5. });

then方法的基础调用写法,可以写一个回调方法,来执行成功后的回调。then方法返回一个的是一个新的Promise实例,因此我们可以采用链式写法,即then方法后面再调用一个then方法。

  1. new Promise((resolve, reject) => {
  2. resolve('王小端Coder');
  3. }).then(res => res).then(res => {
  4. console.log(res); // 王小端Coder
  5. });

采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。

Promise的语法糖catch

catch是用于指定发生错误的回调函数。

  1. new Promise((resolve, reject) => {
  2. reject('失败');
  3. }).catch(error => {
  4. console.log(error); // 失败
  5. });

Promise实例当状态改变为rejected状态或者操作失败抛出异常错误,就会被catch方法捕获。所以在Promise实例中reject方法等同于抛出错误。如果Promise的状态已经变成了resolved,再抛出错误无效。

  1. new Promise((resolve, reject) => {
  2. reject('失败');
  3. throw new Error('抛出异常'); // 这行无效
  4. }).catch(error => {
  5. console.log(error); // 失败
  6. });

Promise的finally方法

finally方法用于指定不管Promis对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。

  1. new Promise((resolve, reject) => {
  2. resolve();
  3. }).then(res => {
  4. console.log('success');
  5. }).catch(error => {
  6. console.log('error');
  7. }).finally(() =>{
  8. console.log('finally');
  9. })

Promise的all方法

Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例。在all方法中可以传递多个Promise对象,当所有的Promise对象状态都返回fufilled,才会返回fulfilled,否则返回rejected。

  1. const promise1 = new Promise((resolve, reject) => {
  2. resolve();
  3. })
  4. const promise2 = new Promise((resolve, reject) => {
  5. resolve();
  6. })
  7. const promise3 = new Promise((resolve, reject) => {
  8. resolve();
  9. })
  10.  
  11. const promiseAll = Promise.all([promise1, promise2, promise3]).then(res => {
  12. console.log('all');
  13. })

Promise的race方法

Promise.race方法同样是将多个Promise实例,包装成一个新的Promise实例。可以传递多个Promise对象作为参数,如果实例红有一个实例率先改变状态,那么race的状态就会跟着改变。

  1. const promise1 = new Promise((resolve, reject) => {
  2. reject();
  3. })
  4. const promise2 = new Promise((resolve, reject) => {
  5. resolve();
  6. })
  7. const promise3 = new Promise((resolve, reject) => {
  8. reject();
  9. })
  10.  
  11. const promiseRace = Promise.race([promise1, promise2, promise3]).then(res => {
  12. console.log('race then');
  13. }).catch(error => {
  14. console.log('race catch');
  15. })

Promise 结束!谢谢大家能够指出其中的不足。

整理一下Promise 的用法的更多相关文章

  1. 简单谈谈js中Promise的用法

    首先先推荐一篇博文:http://blog.csdn.net/jasonzds/article/details/53717501 这篇博文很清晰的说明了Promise的用法,这里来简单总结一下: Pr ...

  2. JavaScript异步与Promise基本用法(resolve与reject)

    Promise解决的问题相信每个前端都遇到过这样一个问题,当一个异步任务的执行需要依赖另一个异步任务的结果时,我们一般会将两个异步任务嵌套起来,这种情况发生一两次还可以忍,但是发生很多次之后,就形成了 ...

  3. 理解并掌握Promise的用法

    前沿:  Promise在处理异步操作非常有用.项目中,与后端进行数据请求的时候经常要用到Promise.我们可以用promise + xhr进行ajax的封装.也可以使用基于promise封装的请求 ...

  4. [js高手之路] es6系列教程 - promise常见用法详解(resolve,reject,catch,then,all,race)

    关于promise我在之前的文章已经应用过好几次,如[js高手之路]Node.js+jade+express+mongodb+mongoose+promise实现todolist,本文就来讲解下pro ...

  5. Promise的用法

    promise.then().promise.catch().Promise.all()... Promise 构造函数接受一个函数作为参数,该函数的2个参数分别是 resolve 和 reject. ...

  6. ES6关于Promise的用法

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

  7. ES6的promise函数用法讲解

    总结:Promise函数的出现极大的解决了Js中的异步调用代码逻辑编写太过复杂的问题,Promise对象让异步调用函数的流程显得更加的优雅,也更容易编写. 举例: 1. 异步调用: 假设现在我的一个页 ...

  8. 入门Promise的用法

    new Promise(function(resolve,reject){ resolve(); //数据处理完成 reject(); //数据处理出错 }).then(function A(){ / ...

  9. ES6关于Promise的用法详解

    Node的产生,大大推动了Javascript这门语言在服务端的发展,使得前端人员可以以很低的门槛转向后端开发. 当然,这并不代表迸发成了全栈.全栈的技能很集中,绝不仅仅是前端会写一些HTML和一些交 ...

随机推荐

  1. osg MatrixManipulator CameraManipulator

    <osgGA/MatrixManipulator>:No such file or directory 修改为 #include <osgGA/CameraManipulator&g ...

  2. CentOS7下搭建Tomcat服务器

    Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试 JSP 程序的首选.Tomcat 和 IIS ...

  3. 解决微信小程序textarea层级太高遮挡其他组件的问题

    <view class='remark'> <view class='title'> 备注说明 </view> <textarea class='mark_t ...

  4. python面向对象之类属性,实例属性

    python中的属性分为类属性和实例属性,之前已经说过一些,这里主要是对类属性与实例属性的增删改查 首先是对类属性的增删改查,下面这个是对类属性的修改,在书写类时,已经对类属性occupation进行 ...

  5. Zabbix设置触发器调用远程主机脚本实现触发告警后自动启动自愈功能

    参考:https://www.cnblogs.com/xiami-xm/p/8929163.html 当zabbix添加触发器后触发告警后可以设置发送邮件及短信告警,但是恢复故障需要运维人员收到告警以 ...

  6. DOS与cmd(windows)

    dos是计算机的最初期的操作系统,对电脑操作必须输入各种dos命令窗口,可以理解成运行计算机机器内部语言,知道编程吗?其实早期dos命令操作系统就是运行计算机内部的编程命令,因此操作人员都必须具有一定 ...

  7. 【C#设计模式2】简单工厂模式

    我们在编程的时候,每当"new"一个对象之后,这个对象就依赖于这个类了.如果在后期的维护过程中由于某些原因需要修改一下这个类,则唯一的做法就是打开源代码,进行修改,修改所有与这个对 ...

  8. 使用Apache服务部署网站(基于IP,域名,端口)

    本篇主要学习Apache网站服务程序的基本部署,基于IP地址.主机名(域名).端口号的虚拟主机功能. 1.基于IP地址 首先我们需要在虚拟机中线安装Apache服务程序,Apache服务程序的软件包名 ...

  9. [tensorflow] 入门day1-数据整理与展示

    tensorflow真是一个我绕不开的坑(苍天饶过谁.jpg) 其实tensorflow1和2的差别挺大的,暂时从1入坑,2的话之后简单过一下. tf2中更改的函数(供参考):https://docs ...

  10. web 系统发展历程

    文章目录 web系统的发展历程 ------- **单机`mysql`的美好年代** ------ **Memcached(缓存)+Mysql+垂直拆分** ------ **mysql 主从读写分离 ...