当前位置: 首页 > news >正文

ES6 Promise

1、概述

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。

Promise对象有以下两个特点。

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

 

Promise一共只有三种状态。状态一旦改变就不会在变,任何时候都能得到这个结果。通过对Promise添加回调,会立即得到这个结果。

 

2、创建Promise

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

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

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。

Promise 新建后就会立即执行。

let promise = new Promise(function(resolve, reject) {
  console.log('Promise');
  resolve();
});

promise.then(function() {
  console.log('resolved.');
});

console.log('Hi!');

上面代码中,Promise 新建后立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出。

 

3、示例(异步加载图片的例子)

function loadImageAsync(url) {
  return new Promise(function(resolve, reject) {
    const image = new Image();

    image.onload = function() {
      resolve(image);
    };

    image.onerror = function() {
      reject(new Error('Could not load image at ' + url));
    };

    image.src = url;
  });
}

上面代码中,使用Promise包装了一个图片加载的异步操作。如果加载成功,就调用resolve方法,否则就调用reject方法。

4、Promise与事件的区别

 

promise和事件类似,你可以把它看成只触发两个事件的event对象,但是事件具有即时性,触发之后这个状态就不存在了,这个事件已经触发过了,你就再也拿不到值了,而promise不同,promise只有两个状态resolve和reject,当它触发任何一个状态后它会将当前的值缓存起来,并在有回调函数添加进来的时候尝试调用回调函数,如果这个时候还没有触发resolve或者reject,那么回调函数会被缓存,等待调用,如果已经有了状态(resolve或者reject),则立刻调用回调函数。并且所有回调函数在执行后都立即被销毁

 

 5、理解

Promise的作用了,简单来讲,就是能把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数

Promise的优势在于,可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作。Promise能够简化层层回调的写法。

通俗理解见:https://www.cnblogs.com/lvdabao/p/es6-promise-1.html

 

6、2018.12.29 更新

Promise.all 的返回值是数组对象。

Promise.race 的返回值是一个promise对象。

 

 7、then 等待的是谁?

若上一个promise有返回值,则等待上一个promise的fulfilled。

若上一个没有return,则使用最开始的promsie。

 8、catch

Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。

getJSON('/post/1.json').then(function(post) {
  return getJSON(post.commentURL);
}).then(function(comments) {
  // some code
}).catch(function(error) {
  // 处理前面三个Promise产生的错误
});

上面代码中,一共有三个 Promise 对象:一个由getJSON产生,两个由then产生。它们之中任何一个抛出的错误,都会被最后一个catch捕获

相关文章:

  • 什么是字符串常量池
  • Shell实战训练营Day11
  • java并发处理 (同步与原子性)
  • Java入门项目:学生信息管理系统V2
  • IE6不支持a标签以外元素的hover的解决方案
  • 40个Java多线程问题详解复习
  • 【Linux】目录权限与文件权限
  • YUV数据格式与YUV_420_888
  • vue-cli3.0项目中使用vw——相比flexible更原生的移动端解决方案
  • rsync 数据镜像备份 记录
  • Lucene:基于Java的全文检索引擎简介
  • Android 其他特效展示
  • DataUml Design 教程7 - 数据库生成模型
  • request
  • luanet分布式lua框架
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • 〔开发系列〕一次关于小程序开发的深度总结
  • angular2 简述
  • axios 和 cookie 的那些事
  • ES6系统学习----从Apollo Client看解构赋值
  • Java教程_软件开发基础
  • Mysql优化
  • Otto开发初探——微服务依赖管理新利器
  • PHP的Ev教程三(Periodic watcher)
  • Rancher-k8s加速安装文档
  • 初识 beanstalkd
  • 学习JavaScript数据结构与算法 — 树
  • Android开发者必备:推荐一款助力开发的开源APP
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #{}和${}的区别是什么 -- java面试
  • #stm32驱动外设模块总结w5500模块
  • #预处理和函数的对比以及条件编译
  • (1)bark-ml
  • (八十八)VFL语言初步 - 实现布局
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (七)理解angular中的module和injector,即依赖注入
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (转)程序员技术练级攻略
  • .equals()到底是什么意思?
  • .NET Core使用NPOI导出复杂,美观的Excel详解
  • .net MVC中使用angularJs刷新页面数据列表
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .Net 应用中使用dot trace进行性能诊断
  • .net/c# memcached 获取所有缓存键(keys)
  • .NetCore 如何动态路由
  • .net访问oracle数据库性能问题
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • .NET连接MongoDB数据库实例教程
  • :not(:first-child)和:not(:last-child)的用法
  • @data注解_一枚 架构师 也不会用的Lombok注解,相见恨晚
  • @GetMapping和@RequestMapping的区别
  • [Big Data - Kafka] kafka学习笔记:知识点整理
  • [BZOJ1060][ZJOI2007]时态同步 树形dp