浅谈es6 promise
本文是借鉴于ac黄的博客。
接触es6也有几个月了,貌似没有系统的去学习过它,总是用到什么,查查什么。今天就说下es6中的promise对象。
先说说promise解决了什么问题?
写前端的同学都经常遇到这种问题:在多个接口异步请求数据,然后利用这些数据来进行一系列的操作。一般如下实现:
$.ajax({
url: '......',
success: function (data) {
//基于data,才能进行下发操作
$.ajax({
url: '......',
success: function (data) {
// ......
}
});
}
});
这样写会导致两个缺点:
在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够直观,就是常说的 Callback Hell。
如果几个异步操作之间并没有前后顺序之分(例如不需要前一个请求的结果作为后一个请求的参数)时,同样需要等待上一个操作完成再实行下一个操作。
es6中的Promise对象就来解决这个问题。
何为Promise对象?
一个 Promise 对象可以理解为一次将要执行的操作(常常被用于异步操作),使用了 Promise 对象之后可以用一种链式调用的方式来组织代码,让代码更加直观(解决第1项缺点)。而且由于 Promise.all 这样的方法存在,可以让同时执行多个操作变得简单(解决第2项缺点)。
resolve 和 reject
大家可以用把下方这段代码贴到浏览器开发模式中的console中运行,看看结果。
function helloWorld (ready) {
return new Promise(function (resolve, reject) {
if (ready) {
resolve("Hello World!");
} else {
reject("Good bye!");
}
});
}
helloWorld(true).then(function (message) {
alert(message);
}, function (error) {
alert(error);
});
结果是,浏览器弹出 “hello world!”.
上面的代码实现的功能非常简单,helloWord 函数接受一个参数,如果为 true 就打印 "Hello World!",如果为 false 就打印错误的信息。helloWord 函数返回的是一个 Promise 对象。
在 Promise 对象当中有两个重要方法————resolve 和 reject。
resolve 方法可以使 Promise 对象的状态改变成成功,同时传递一个参数用于后续成功后的操作,在这个例子当中就是 Hello World! 字符串。
reject 方法则是将 Promise 对象的状态改变为失败,同时将错误的信息传递到后续错误处理的操作。
Promise 对象有三种状态:
Fulfilled 可以理解为成功的状态
Rejected 可以理解为失败的状态
Pending 既不是 Fulfilld 也不是 Rejected 的状态,可以理解为 Promise 对象实例创建时候的初始状态
helloWorld 的例子中的 then 方法就是根据 Promise 对象的状态来确定执行的操作,resolve 时执行第一个函数(onFulfilled),reject 时执行第二个函数(onRejected)。
then 和 catch
then
helloWorld 的例子当中利用了 then(onFulfilld, onRejected) 方法来执行一个任务打印 "Hello World!",在多个任务的情况下 then方法同样可以用一个清晰的方式完成。
例如:
function printHello (ready) {
return new Promise(function (resolve, reject) {
if (ready) {
resolve("Hello");
} else {
reject("Good bye!");
}
});
}
function printWorld () {
alert("World");
}
function printExclamation () {
alert("!");
}
printHello(true)
.then(function(message){
alert(message);
})
.then(printWorld)
.then(printExclamation);
结果是顺序弹出:“Hello”“World”“!”
then 可以使用链式调用的写法原因在于,每一次执行该方法时总是会返回一个 Promise 对象。另外,在 then onFulfilled 的函数当中的返回值,可以作为后续操作的参数。因此上面的方法可以写为:
function printHello (ready) {
return new Promise(function (resolve, reject) {
if (ready) {
resolve("Hello");
} else {
reject("Good bye!");
}
});
}
printHello(true).then(function (message) {
return message;
}).then(function (message) {
return message + ' World';
}).then(function (message) {
return message + '!';
}).then(function (message) {
alert(message);
});
结果输出是:“Hello World!”。
catch
catch 方法是 then(onFulfilled, onRejected) 方法当中 onRejected 函数的一个简单的写法,也就是说可以写成 then(fn).catch(fn),相当于 then(fn).then(null, fn)。使用 catch 的写法比一般的写法更加清晰明确。
Promise.all 和 Promise.race
Promise.all 可以接收一个元素为 Promise 对象的数组作为参数,当这个数组里面所有的 Promise 对象都变为 resolve 时,该方法才会返回。
var p1 = new Promise(function (resolve) {
setTimeout(function () {
resolve("Hello");
}, 3000);
});
var p2 = new Promise(function (resolve) {
setTimeout(function () {
resolve("World");
}, 1000);
});
Promise.all([p1, p2]).then(function (result) {
console.log(result); // ["Hello", "World"]
});
上面的例子模拟了传输两个数据需要不同的时长,虽然 p2 的速度比 p1 要快,但是 Promise.all 方法会按照数组里面的顺序将结果返回。
日常开发中经常会遇到这样的需求,在不同的接口请求数据然后拼合成自己所需的数据,通常这些接口之间没有关联(例如不需要前一个接口的数据作为后一个接口的参数),这个时候 Promise.all 方法就可以派上用场了。
Promise.race 和 Promise.all 方法类似,它同样接收一个数组,不同的是只要该数组中的 Promise 对象的状态发生变化(无论是 resolve 还是 reject)该方法都会返回。
兼容性
在浏览器端,一些主流的浏览器都已经可以使用 Promise 对象进行开发,在 Node.js 配合 babel 也可以很方便地使用。
如果要兼容旧的浏览器,建议可以寻找一些第三方的解决方案,例如 jQuery 的 $.Deferred。

浅谈es6 promise的更多相关文章
- 浅谈ES6原生Promise
浅谈ES6原生Promise 转载 作者:samchowgo 链接:https://segmentfault.com/a/1190000006708151 ES6标准出炉之前,一个幽灵,回调的幽灵,游 ...
- ES6浅谈之Promise
首先来回想一下Promise对象的写法: // 方法1 let promise = new Promise ( (resolve, reject) => { if ( success ) { . ...
- 浅谈ES6基础——Promise
IMAGE加载 Callback Hell function loadImg(src,callback,fail) { var img = document.createElement('img'); ...
- 浅谈ES6新特性
ES6的了解 新增模板字符串(为JavaScript提供了简单的字符串插值功能).箭头函数(操作符左边为输入的参数,而右边则是进行的操作以及返回的值Inputs=>outputs.).for-o ...
- 浅谈 es6 箭头函数, reduce函数介绍
今天来谈一下箭头函数, es6的新特性 首先我们来看下箭头函数长什么样子, let result = (param1, param2) => param1+param2; 上述代码 按照以前书写 ...
- 浅谈ES6
ECMAScript6.0(简称ES6)是javaScript语言的下一代标准,已经在2015年6月正式发布了.它的目标,使得javaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言 ...
- 浅谈ES6新增数据类型:Symbol
面试中喜闻乐见的问题就是问我们的ES6新增了哪些个新特性 这篇文章一起学习一下新增的数据类型:Symbol JS的原始数据类型:6种Boolean,String,Undefined,NULL,Numb ...
- 浅谈ES6——ES6中let、const、var三者的区别
在了解let.const.var的区别之前,先了解一些什么是es6 Es6 全称ECMAscript 是JavaScript语言的一个标准,其实Es6本质就是JavaScript的一个版本,为什么叫E ...
- 浅谈ES6数组及对象的解构
一.数组的解构,ES6的新特性,主要是方便操作数组,节省不必要的代码,提高代码质量. 上图例子中, example1: 之前想要获取数组中的值,只能挨个获取下标,然后取值 example2:ES6新特 ...
随机推荐
- 【bzoj1787】&【bzoj1832】[Ahoi2008]Meet 紧急集合 & 聚会
bzoj1787就是bzoj1832 bzoj1832 空间和时间少了一些... 求三个结点到一个结点距离之和最小的结点以及距离和 求出两两lca,其中有两个相同,答案则为另一个 感觉就是一大暴力.. ...
- redis Database Eviction Policies Redis on Flash
Database Eviction Policies - Redis Enterprise Software | Redis Labs https://redislabs.com/redis-ente ...
- 2015-2016 ACM-ICPC Pacific Northwest Regional Contest (Div. 2)V - Gears
Problem V | limit 4 secondsGearsA set of gears is installed on the plane. You are given the center c ...
- 逻辑频道号---DVB NIT LCN
先介绍NIT,NIT描述如下: 有一点要注意,NIT是对大网的描述,即NIT并不是描述当前的流,而是描述大网的某些或者全部流.如下图,TS流描述1-6共对6个频点不同的TS流进行了描述,具体对哪一个流 ...
- uva11542
https://vjudge.net/problem/UVA-11542 xor高斯消元... 答案为2^f-1 其实书上有一个问题 样例有3种情况,其中4,6,15是绑在一起的,也就是他们必须满足一 ...
- bzoj4534: 基础排序算法练习题
传送门 策爷的论文题啊……题解在这儿 我只想知道为什么这题的弱化版会出现在我们今天的%你赛里…… 题意:给你一堆操作$(l,r)$,表示将区间$(l,r)$按升序排序.以及$q$个询问,每次询 ...
- golang——database/sql包学习
1.database/sql包 sql包提供了保证SQL或类SQL数据库的泛用接口. 使用sql包时必须注入(至少)一个数据库驱动. (1)获取mysql driver:go get -v githu ...
- (博弈论)51NOD 1072 威佐夫游戏
有2堆石子.A B两个人轮流拿,A先拿.每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取.拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出2堆石子的数量, ...
- c#自定义ORM框架---(泛型&反射&实体类扩展属性<附带通用增、删、查、改>)
该教材主要是运用到泛型.反射和实体类扩展属性 步骤一.建立扩展属性类 实体类扩展属性要继承Attribute基类完成 [AttributeUsage(AttributeTargets.Property ...
- jQuery——表单应用(4)
HTML: <!--复选框应用--> <!DOCTYPE html> <html> <head> <meta charset="UTF- ...