ES6新增Promise
1.promise概念
ES6 原生提供了 Promise 对象。
所谓 Promise,就是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。
Promise 对象有以下两个特点。
(1)对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供统一的接口,使得控制异步操作更加容易。
Promise 也有一些缺点。首先,无法取消 Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。第三,当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
var promise = new Promise(function(resolve, reject) {
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
}); promise.then(function(value) {
// success
}, function(value) {
// failure
});
2.举个例子
“小妞妞,嫁给我吧!我发誓,我会对你一辈子好的!”
“这个嘛,你先去问问我爸爸,我大伯以及我大姑的意思,他们全部都认可你,我再考虑考虑!对了,如果我爸没有答复,大伯他们肯定是不会同意的;如果大伯没有答复,大姑也是不会同意的。”
传统思维,基于“去搞定岳父→…等待期…结果来了…→去搞定大伯→…等待期…结果来了…→去搞定大姑→…等待期…结果来了…→去搞定女神→…等待期…结果来了…”的思路,中间是很多的嵌套。
男神.请求({
姓名: "岳父",
成功: 男神.继续请求({
姓名: "大伯",
成功: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
}),
失败: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
}),
失败: "求婚失败"
})
}),
失败: 男神.继续请求({
姓名: "大伯",
成功: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
}),
失败: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
}),
失败: "求婚失败"
})
}),
失败: "求婚失败"
})
}),
失败: 男神.请求({
姓名: "岳父",
成功: 男神.继续请求({
姓名: "大伯",
成功: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
}),
失败: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
}),
失败: "求婚失败"
})
}),
失败: 男神.继续请求({
姓名: "大伯",
成功: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
}),
失败: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
}),
失败: "求婚失败"
})
}),
失败: "求婚失败"
})
}),
失败: "求婚失败"
})
})
用模拟promise的方式写的函数,但依次执行的触发依然在回调中。我们可能希望得到的代码具有如下与现实世界统一的思维:“搞定岳父→搞定大伯→搞定大姑→搞定女神”,但是,下面的实现却看不出这样的思维。
// 男神的各项参数
var NanShen = {
"身高": 180,
"体重": 80,
"年薪": "200K",
request: function(obj) {
// 成功与否随机决定
// 执行成功的概率为80%
if (Math.random() > 0.2) {
obj.success();
} else {
obj.error();
}
}
}; var Request = function(names, success) {
var index = 0, first = 0;
var request = function() {
if (names[index]) {
NanShen.request({
name: names[index],
success: function() {
first = 0;
console.log("成功拿下" + names[index]);
index++;
request();
},
error: function() {
if (first == 1) {
console.log("依旧没能拿下" + names[index] + ",求婚失败");
return;
} else {
console.log("没能拿下" + names[index] + ",再试一次");
}
first = 1;
request();
}
});
} else {
success();
}
}; request();
}; Request(["岳父", "大伯", "大姑"], function() {
NanShen.request({
name: "女神",
success: function() {
console.log("女神同意,求婚成功!");
},
error: function() {
console.log("女神不同意,求婚失败!");
}
});
})
带有promise写法的代码是如下:
// 男神的各项参数
var NanShen = {
"身高": 180,
"体重": 80,
"年薪": "200K",
request: function(obj) {
// 成功与否随机决定
// 执行成功的概率为80%
if (Math.random() > 0.2) {
obj.success();
} else {
obj.error();
}
}
}; var Request = function(name) {
return new Promise(function(resolve, reject) {
var failed = 0, request = function() {
NanShen.request({
name: name,
success: function() {
console.log(name + "攻略成功!");
failed = 0;
resolve();
},
error: function() {
if (failed == 0) {
console.log("第一次攻略" + name + "失败,重试一次!");
failed = 1;
// 重新攻略一次
request();
} else {
console.log("依然没有拿下" + name + ",求婚失败!");
reject();
}
}
});
}; request();
});
}; Request("岳父") // 搞定岳父,然后...
.then(function() { return Request("大伯"); }) // 搞定大伯,然后...
.then(function() { return Request("大姑"); }) // 搞定大姑,然后...
.then(function() { // 长辈们全部KO后,攻略女神
NanShen.request({
name: "女神",
success: function() {
console.log("女神同意,求婚成功!");
},
error: function() {
console.log("女神不同意,求婚失败!");
}
});
});
通过在函数中合理的设置resolved()和rejected(),然后通过then()单独设置resolved和rejected的具体操作,可以很直观的用同步的方式表示异步的过程
ES6新增Promise的更多相关文章
- ES6新增"Promise"可避免回调地狱
Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方法,原型上有then.catch等同样很眼熟的方法. 那就new一个 var p = new Promise( ...
- ES6新增常见特性
一:声明属性let const var let const 区别 1.var声明变量会发生变量提升,let.const不会发生变量提升 2.var允许重复声明变量,let不可以 3.const声明变量 ...
- 教你如何使用ES6的Promise对象
教你如何使用ES6的Promise对象 Promise对象,ES6新增的一个全新特性,这个是 ES6中非常重要的一个对象 Promise的设计初衷 首先,我们先一起了解一下,为什么要设计出这么一个玩意 ...
- ES6的promise对象研究
ES6的promise对象研究 什么叫promise? Promise对象可以理解为一次执行的异步操作,使用promise对象之后可以使用一种链式调用的方式来组织代码:让代码更加的直观. 那我们为什么 ...
- es6新增
首先要说let,他是只在代码块中执行的变量,例如: { let a = 10; var b = 1;}console.log(a);//definedconsole.log(b);//1 ...
- ECMAScript简介以及es6新增语法
ECMAScript简介 ECMAScript与JavaScript的关系 ECMAScript是JavaScript语言的国际化标准,JavaScript是ECMAScript的实现.(前者是后者的 ...
- ES6新增的常用数组方法(forEach,map,filter,every,some)
ES6新增的常用数组方法 let arr = [1, 2, 3, 2, 1]; 一 forEach => 遍历数组 arr.forEach((v, i) => { console.log( ...
- ES6新增对象方法的访问描述符:get(只读)、set(只写)
Es6新增对象方法的访问描述符:get(只读).set(只写),可以直接使用,一般用于数据监听,用途类似于vue.$watch. var obj = { a:1, get bar() { return ...
- 浅谈ES6新增数据类型:Symbol
面试中喜闻乐见的问题就是问我们的ES6新增了哪些个新特性 这篇文章一起学习一下新增的数据类型:Symbol JS的原始数据类型:6种Boolean,String,Undefined,NULL,Numb ...
随机推荐
- 信号之sigprocmask函数
一个进程的信号屏蔽字规定了当前阻塞而不能递送给该进程的信号集.调用函数sigprocmask可以检测或更改其信号屏蔽字,或者在一个步骤中同时执行这两个操作. #include <signal.h ...
- 如何在Linux下拷贝一个目录呢
cp -af newadmin/movie/. uploadfile/mallvideo/ 如何在Linux下拷贝一个目录呢?这好像是再简单不过的问题了. 比如要把/home/usera拷贝到/m ...
- U_boot 的 bootcmd 和bootargs参数详解
转自 :http://linux.chinaunix.net/bbs/archiver/tid-1111568.html U-boot的环境变量值得注意的有两个: bootcmd 和bootargs. ...
- .NET和SQL Server中“空值”辨析 (DBNull与Null的区别)
对表进行插入操作,如datetime和int类型的两个字段,都允许为null,用“sqlcmd.Parameters.Add("@t12",tb12.Text)”参数绑定时.dat ...
- 【开源项目8】Android开源项目分类汇总【畜生级别】
欢迎大家推荐好的Android开源项目,可直接Commit或在 收集&提交页 中告诉我,欢迎Star.Fork :) 微博:Trinea 主页:www.trinea.cn 邮箱:t ...
- ls与dir的区别
1.ls具有上色的效果,dir没有. 2.ls是unix/linux系列的命令,dir是dos/windows系列的命令.
- CALayer 简单操作和实际应用
1.CALayer //每一个UIView,都存在一个CALayer.(主层) //CALayer的功能 描边,圆角,阴影... //CALayer 属于QuartzCore绘图框架 //明明有UIC ...
- 查询SQL SERVER数据库日志工具
在SQL SERVER中查看操作日志,一直是一个比较麻烦的事情,因为微软并没有提供直接的系统工具可以查看日志内容,虽然可以通过非正式的隐藏接口dbcc log 获取日志的非解析编码但是要还原是个非常麻 ...
- javascript线程解释(setTimeout,setInterval你不知道的事)---转载
在工作中,可能我们经常遇到在有很多 setInterval 的页面, 再手动触发 setTimeout 的时候经常失败, 尤其是 jquery做动画的时候,一些渐入溅出的东西,很多东西都不被触发……, ...
- IE浏览器部分版本不支持background-siza属性问题
background-size是CSS3新增的属性,但是IE8以下还是不支持,可以通过滤镜来实现这样的一个效果 background-size:contain; // 缩小图片来适应元素的尺寸(保持像 ...