深入浅出理解Promise

1.Promise 的含义

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

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

Promise对象有以下两个特点。

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

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

注意,为了行文方便,本章后面的resolved统一只指fulfilled状态,不包含rejected状态。

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

Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

详细请参考ES6文档

2.基本用法

首先Promise对象是一个构造函数,使用它需要用new一个promise实例:

 1)var promise = new Promise(function(resolve, reject) {

  // ... some code这里边是我们具体实现的异步操作逻辑

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

另外,promise对象返回的可以是数值,也可以是一个promise实例。
var p1 = new Promise(function (resolve, reject) {
  // ...
});

var p2 = new Promise(function (resolve, reject) {
  // ...
  resolve(p1);
})


2)实例化promise对象之后,我们就可以用对象的实例方法then()来处理异步操作返回的结果。promise.then( value=>{//value拿到异步操作返回的结果//...some code
})另外,实例的then()方法是可以链式调用的。

3.Promise.prototype.catch()

Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。

一般来说,不要在then方法里面定义Reject状态的回调函数(即then的第二个参数),总是使用catch方法。

一般总是建议,Promise 对象后面要跟catch方法,这样可以处理 Promise 内部发生的错误。catch方法返回的还是一个 Promise 对象,因此后面还可以接着调用then方法。

var someAsyncThing = function() {
  return new Promise(function(resolve, reject) {
    // 下面一行会报错,因为x没有声明
    resolve(x + 2);
  });
};

someAsyncThing()
.catch(function(error) {
  console.log(‘oh no‘, error);
})
.then(function() {
  console.log(‘carry on‘);
});
// oh no [ReferenceError: x is not defined]
// carry on

4.Promise.all()

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

var p = Promise.all([p1, p2, p3]);

上面代码中,Promise.all方法接受一个数组作为参数,p1p2p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。(Promise.all方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。)

p的状态由p1p2p3决定,分成两种情况。

(1)只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

下面是一个具体的例子。

// 生成一个Promise对象的数组
var promises = [2, 3, 5, 7, 11, 13].map(function (id) {
  return getJSON(‘/post/‘ + id + ".json");
});

Promise.all(promises).then(function (posts) {
  // ...
}).catch(function(reason){
  // ...
});

上面代码中,promises是包含6个 Promise 实例的数组,只有这6个实例的状态都变成fulfilled,或者其中有一个变为rejected,才会调用Promise.all方法后面的回调函数。

经常用到的就这几个。



时间: 2024-10-12 21:53:28

深入浅出理解Promise的相关文章

理解Promise的3种姿势

译者按: 对于Promise,也许你会用了,却并不理解:也许你理解了,却只可意会不可言传.这篇博客将从3个简单的视角理解Promise,应该对你有所帮助. 原文: Three ways of understanding Promises 译者: Fundebug 为了保证可读性,本文采用意译而非直译,并且对源代码进行了大量修改.另外,本文版权归原作者所有,翻译仅用于学习. 示例1中,asyncFunc()函数返回的是一个Promise实例: // 示例1 function asyncFunc()

0524.深入浅出理解iOS常用的正则表达式—基础篇[Foundation]

参考资料:cocoachina的zys475481075的文章 几个单词 Regular  ['regj?l?] adj. 定期的:有规律的 Expression [?k'spre?(?)n; ek-] n. 表现,表示 Regular expression 正则表达式 什么是正则表达式? 用一个描述字符串去验证另一个字符串是否符合描述字符串的特征.(不严谨,可以这么理解) 思考:比如表达式"12+",描述的意思是一个1和任意个2组成的字符串,那么'12'.'122'.'122'-.都

160701、理解 Promise 的工作原理

Javascript 采用回调函数(callback)来处理异步编程.从同步编程到异步回调编程有一个适应的过程,但是如果出现多层回调嵌套,也就是我们常说的厄运的回调金字塔(Pyramid of Doom),绝对是一种糟糕的编程体验.于是便有了 CommonJS 的 Promises/A 规范,用于解决回调金字塔问题.本文先介绍 Promises 相关规范,然后再通过解读一个迷你的 Promises 以加深理解. 什么是 Promise   一个 Promise 对象代表一个目前还不可用,但是在未

深入浅出理解c++虚函数

深入浅出理解c++虚函数 记得几个月前看过C++虚函数的问题,当时其实就看懂了,最近笔试中遇到了虚函数竟然不太确定,所以还是理解的不深刻,所以想通过这篇文章来巩固下. 装逼一刻: 最近,本人思想发生了巨大的转变,在大学的时候由于读书少,经常写一些玩具程序而沾沾自喜,总之一句话,那时写程序纯粹是为了写程序而写程序.然而,作为大部分的学习者来说,往往忽略了学习开发语言的本质.即C++语言的设计思想也是以服务生产生活为主的,总结成一句话就是C++是实用的.我们在学习这门语言的一些特性的时候,上来就开始

理解promise

原文地址: http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html 用Javascript的小伙伴们,是时候承认了,关于 promises 我们一直存在着问题.并非说 promises 本身有问题,Promises/A+ 是极好的. 就我过去数年观察大量 PouchDB API 以及其他 promise-heavy API 的使用者们与这些 API 的搏斗中我发现,最大的问题是: 大部分使用 promises 的小伙伴

JavaScript:理解Promise方法

什么是promise? Promise的核心思想是代表异步操作的一个结果,并且promise具有三个状态(pending初始状态,fulfilled成功状态,rejected失败状态).我们可以理解为使用promise可以实现非阻塞io的功能,根据三个不同的状态,我们可以知道回调函数实现在哪个过程. Promise.prototype.then 源码分析: 1 this.then = function(onFulfilled) { 2 if (typeof onFulfilled !== "fu

深入理解Promise并写一个符合Promise a+规范的Promise代码

关于Promise函数可以参考我写的这篇文章https://www.cnblogs.com/qiaohong/p/7705262.html,我们现在就深入理解一下这个函数. 首先说下Promise方法,Promise方法中还是有些是比较好用的,比如说Promise.all()方法(Promise.all()方法的参数是一个数组,会按照数组的结果放到成功的回调里,如果有一个错误那么就不会成功).Promise.race()方法(这个方法的参数也是一个数组,Promise.race()会同时发起并发

理解Promise.all,Promise.all与Promise.race的区别,如何让Promise.all在rejected后依然返回resolved状态

 壹 ? 引 我在 es6入门4--promise详解 这篇文章中有详细介绍Promise对象的用法,文章主题更偏向于对于Promise概念的理解与各方法基本使用介绍:而世上一个比较有趣的问题就是,即便按照前人提供的规则与方法去做一件事,也会因为未知的缘故产生新问题,这让人非常苦恼,但大多数情况都是因为自身理解不深刻导致:在昨天的工作中使用Promise.all的经历也是把我整的不轻(最后查出来是后台逻辑BUG...),这也是我想另起一篇文章专门介绍Promise.all与Promise.rac

深入浅出理解绝对定位和相对定位

原文地址:http://www.360doc.com/content/10/0814/18/1001775_46037316.shtml 概要: 本文主要描述XHTML中相对定位和绝对定位各自的本质.用法.区别和两者之间的关系.以及使用CSS的Left.Right.Top.Bottom属性(偏移属性)和Margin属性(外边距)对定位块级元素进行布局的方法. 说明: 占位空间:元素在文档流中所占据的空间. 物理空间:元素本身所占据的空间. 下面分3种情况分别对相对定位和绝对定位进行讨论: 1.