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的更多相关文章

  1. ES6新增"Promise"可避免回调地狱

    Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方法,原型上有then.catch等同样很眼熟的方法. 那就new一个 var p = new Promise( ...

  2. ES6新增常见特性

    一:声明属性let const var let const 区别 1.var声明变量会发生变量提升,let.const不会发生变量提升 2.var允许重复声明变量,let不可以 3.const声明变量 ...

  3. 教你如何使用ES6的Promise对象

    教你如何使用ES6的Promise对象 Promise对象,ES6新增的一个全新特性,这个是 ES6中非常重要的一个对象 Promise的设计初衷 首先,我们先一起了解一下,为什么要设计出这么一个玩意 ...

  4. ES6的promise对象研究

    ES6的promise对象研究 什么叫promise? Promise对象可以理解为一次执行的异步操作,使用promise对象之后可以使用一种链式调用的方式来组织代码:让代码更加的直观. 那我们为什么 ...

  5. es6新增

    首先要说let,他是只在代码块中执行的变量,例如: {    let a = 10;    var b = 1;}console.log(a);//definedconsole.log(b);//1 ...

  6. ECMAScript简介以及es6新增语法

    ECMAScript简介 ECMAScript与JavaScript的关系 ECMAScript是JavaScript语言的国际化标准,JavaScript是ECMAScript的实现.(前者是后者的 ...

  7. ES6新增的常用数组方法(forEach,map,filter,every,some)

    ES6新增的常用数组方法 let arr = [1, 2, 3, 2, 1]; 一 forEach => 遍历数组 arr.forEach((v, i) => { console.log( ...

  8. ES6新增对象方法的访问描述符:get(只读)、set(只写)

    Es6新增对象方法的访问描述符:get(只读).set(只写),可以直接使用,一般用于数据监听,用途类似于vue.$watch. var obj = { a:1, get bar() { return ...

  9. 浅谈ES6新增数据类型:Symbol

    面试中喜闻乐见的问题就是问我们的ES6新增了哪些个新特性 这篇文章一起学习一下新增的数据类型:Symbol JS的原始数据类型:6种Boolean,String,Undefined,NULL,Numb ...

随机推荐

  1. iOS开发——图层OC篇&UIColor深入研究(CGColor,CIColor)

    UIColor深入研究(CGColor,CIColor) 由于跟人比较喜欢研究关于图层与动画方面的技术,正打算看看别人写的好东西,就遇到了好几个问题, 第一:UIClor类方法的使用 就是关于UICo ...

  2. this class is not key value coding-compliant for the key XXX错误的解决方法

    转自:http://www.cnblogs.com/zhangronghua/archive/2012/03/16/iOSError1.html 今天在听iOS开发讲座时,照着讲座的demo输入代码, ...

  3. LeetCode27 Remove Element

    题目: Given an array and a value, remove all instances of that value in place and return the new lengt ...

  4. Mac上如何修改默认打开方式

    1.找到要打开的文件 2.右键显示简介 3.选择默认程序

  5. JavaScript中数组操作

    var arr1=new Array(); arr1.push(1);//在数组的中末尾添加元素,并返回新的长度 arr1.push(2);//在数组的中末尾添加元素,并返回新的长度 arr1.pop ...

  6. D. Ilya and Escalator

    D. Ilya and Escalator time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  7. 02.Java多线程并发库API使用

    1.        传统线程技术回顾 继承线程与实现Runnable的差异?为什么那么多人都采取第二种方式? 因为第二种方式更符合面向对象的思维方式.创建一个线程,线程要运行代码,而运行的代码都封装到 ...

  8. c# 将文本中的数据快速导入到数据库(200万左右的数据量)

    1.sql2008中 list表,只有一个字段 Lvalue 2.文本大约256万的数据量 3.测试结果:用时36秒! string connStr = @"Data Source=.\SQ ...

  9. nginx设置SSL反向代理

    Nginx的反向代理通常用来映射内网中提供的Apache.IIS.Lighttpd服务,以实现负载均衡:同时,由于动态服务程序运行在内网,服务器的整体安全性也有所提高,那么怎样用nginx设置SSL的 ...

  10. 对象(类)的封装方式(面向对象的js基本知识)

    上一个月一直忙于项目,没写过笔记,今天稍微空下来了一点 前几天在写项目的时候关于怎么去封装每一个组件的时候思考到几种方式,这里总结一下: 1.构造函数方式(类似java写类的方式):把所有的属性和方法 ...