浅谈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新特 ...
随机推荐
- js 获取函数的所有参数名
具体思路: 利用Function.toString()方法,获取到函数的源码,再利用正则匹配获取到参数名字. 实现代码(代码基于ES6): // 获取函数的参数名 function getParame ...
- 危险的input 微博的过去
更改uid post地址不变
- yispider 开源小说採集器 (来源http://git.oschina.net/yispider/yispider 我的改动版由于他的我无法跑)
我的git地址 http://git.oschina.net/yangdc/yispider 小说採集器 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/ ...
- sql加一个%号是什么意思
sql%notfound 是异常SQL%ROWCOUNT SQL语句执行影响的行数SQL%FOUND SQL语句是否成功执行SQL%NOTFOUND SQL语句是否成功执行SQL%ISOPEN 游标是 ...
- Spring的 @ExceptionHandler注解无效问题
如果你想设置了@ExceptionHandler注解进行异常捕获返回异常信息,但是Debug调试时,代码并未进到被@ExceptionHandler注解标注的方法里,那么就检查你的配置文件是否包含 & ...
- Linux下 FACL详解
1. 什么是ACL ACL即Access Control List 主要的目的是提供传统的owner,group,others的read,write,execute权限之外的具体权限设置 ACL可以针 ...
- SP1043 GSS1 - Can you answer these queries I(猫树)
给出了序列A[1],A[2],…,A[N]. (a[i]≤15007,1≤N≤50000).查询定义如下: 查询(x,y)=max{a[i]+a[i+1]+...+a[j]:x≤i≤j≤y}. 给定M ...
- Uva 10766 Organising the Organisation (Matrix_tree 生成树计数)
题目描述: 一个由n个部门组成的公司现在需要分层,但是由于员工间的一些小小矛盾,使得他们并不愿意做上下级,问在满足他们要求以后有多少种分层的方案数? 解题思路: 生成树计数模板题,建立Kirchhof ...
- hdu6198 number number number(递推公式黑科技)
number number number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- 1393 0和1相等串 鸽笼原理 || 化简dp公式
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1393 正解一眼看出来的应该是鸽笼原理.记录每个位置的前缀和,就是dp[i ...