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 ...
随机推荐
- cocos2d-x jsbinding 资源下载实现
cocos2dx没有直接给出资源下载的api,可能是因为资源的管理每个项目的需求不太一样,所以完整的资源下载功能需要我们自己去实现. 资源下载分为两部分,一部分是资源请求,另一部分是资源文件写入.资源 ...
- 信号之sigaction函数
sigaction函数的功能是检查或修改与指定信号相关联的处理动作(或同时执行这两种操作). #include <signal.h> int sigaction( int signo, c ...
- redis源码学习
上帝禁区 http://blog.csdn.net/a600423444/article/details/8944601
- 在应用程序中操作NorFlash
相对于操作NandFlash,操作NorFlash相对简单,因为基本不需要考虑坏块,NorFlash也没有OOB区域,也跟ECC没有一毛钱关系.它的读写擦除相对容易. int dealwithnor( ...
- docker镜像的操作
在主机上列出镜像 sudo docker images 每从Docker Hub下载一个镜像就会启动相对的创建一个容器 在镜像列表中看到三个重要的东西: 来自什么镜像源,例如ubuntu 每个镜像都有 ...
- 1.5.4 什么是Filter--过滤器
什么是Filter--过滤器 像分词器(tokenizer)一样,过滤器(filter)消耗输入,产生token流.过滤器同样从org.apache.lucene.analysis.TokenStre ...
- Android 高级UI设计笔记20:RecyclerView 的详解之RecyclerView添加Item点击事件
1. 引言: RecyclerView侧重的是布局的灵活性,虽说可以替代ListView但是连基本的点击事件都没有,这篇文章就来详细讲解如何为RecyclerView的item添加点击事件,顺便复习一 ...
- 3. Android框架和工具之 xUtils(HttpUtils)
1. HttpUtils 作用: 支持同步,异步方式的请求: 支持大文件上传,上传大文件不会oom: 支持GET,POST,PUT,MOVE,COPY,DELETE,HEAD请求: 下载支持301/3 ...
- Android 高级UI设计笔记10:瀑布流控件PinterestLikeAdapterView的使用
1. 首先我们看看瀑布流的效果,如下: 2. 今天要介绍的瀑布流控件是:PinterestLikeAdapterView 项目地址:https://github.com/GDG-Korea/Pinte ...
- Android学习笔记⑤——UI组件的学习TextView相关
TextView是一个强大的视图组件,直接继承了View,同时也派生出了很多子类,TextView其作用说白了就是在布局中显示文本,有点像Swing编程中的JLabel标签,但是他比JLabel强大的 ...