ES5中实现异步的常见方式不外乎以下几种:

1. 回调函数

2. 事件驱动

2. 自定义事件(根本上原理同事件驱动相同)

而ES6中的Promise的出现就使得异步变得非常简单。promise中的异步是这样的:

* 每当我需要执行一次异步操作的时候,我都需要new一个promise对象

* 每一个异步操作的Promise对象都需要设定一个成功执行的条件和成功的回调、一个失败的条件和失败的回调

* Promise对象可通过执行then()方法获得成功的回调信息

* Promise对象可通过执行catch()方法捕获失败的回调信息(当不执行catch方法时,若异步操作失败会报错)

一次常规异步操作的流程大致是这样的:

    new Promise((resolve, reject)=>{
if(...){ // 设定异步操作成功的条件
resolve() // 设定异步操作成功 并返回 成功的回调信息
}
else{ // 设定异步操作失败的条件
reject() // 设定异步操作失败 并返回 失败的回调
}
})
.then((res)=>{ //执行异步操作,并且执行成功
..... // 异步操作成功后的后续操作
...
..
})
.catch((err)=>{ // 执行一步操作,异步操作失败
..... // 操作失败的后续操作
...
..
})

下面首先通过一个简单的例子来基本套用一下异步操作的流程

实际项目中经常会有这样的需求,很多功能都是需要在登录后才能去实现的,比如说我想要查看用户的个人信息,那么这个用户就必须先要登录,那么分解步骤后

第一步: 执行登录并且登录成功

第二步: 登录成功,开始获取用户信息

第三步: 获取用户信息成功,返回用户信息或成功的回调信息。

以上三步操作,需要两次异步操作,就需要两个异步的Promise对象

首先是准备工作:

    // 两个状态用以分别判断两次异步操作是否成功
let status1 = 1;
let status2 = 1;
// 设定登录的异步操作
let doLogin = (resolve, reject) =>{
setTimeout(()=>{
if(status1 ==1){
resolve({status:1,msg: `异步执行 login ok`})
}else{
reject({status:0,msg: `异步执行 login failed`});
}
},2000)
}
// 设定获取用户信息的异步操作
let getUserInfo = (resolve, reject)=>{
setTimeout(()=>{
if(status2==1){
resolve({status:1,msg: `异步执行 get user info ok`});
}else{
reject({status:0,msg: `异步执行 get user info failed`});
}
},1000)
}

紧接着开始执行异步操作:

    new Promise(doLogin)
.then((res)=>{
if(res.status==1){
console.log(res.msg);
return new Promise(getUserInfo) // 若下一步要执行异步操作则必须返回一个promise对象用以链式操作
}else{
console.log(res.msg);
}
})
.then((res)=>{
console.log(res.msg)
})
.catch((err)=>{
console.log(err.msg)
})

感兴趣的可以通过控制status1、status2两个状态码体验一下不同情况下异步操作的流程与结果。

上面的例子搞清楚之后差不多也就理解了promise的基本用法。

你也可以配合同步代码体验效果:

    console.log("同步执行111111111")
new Promise(doLogin)
.then((res)=>{
if(res.status==1){
console.log(res.msg);
return new Promise(getUserInfo)
}else{
console.log(res.msg);
}
})
.then((res)=>{
console.log(res.msg)
})
.catch((err)=>{
console.log(err.msg)
})
console.log("同步执行2222222")

而当你需要实现连续的异步操作时,需要在每一步异步操作后都返回一个promise对象,否则执行的还是同步操作。下面的例子可以证明:

    let afterLogin1 = ()=>{
console.log("登录后续操作1")
}
let afterLogin2 = ()=>{
console.log("登录后续操作2")
} new Promise(doLogin)
.then((res)=>{
console.log(res.msg)
})
.then((res)=>{
setTimeout(()=>{
afterLogin1();
},1000)
})
.then((res)=>{
afterLogin2();
})

例子的输出结果为:

异步执行 login ok

登录后续操作2

登录后续操作1

 Promise.all()   多异步操作,所有异步执行需全部成功

all()  方法需要传入的参数为对象数组,只有当数组中的所有异步对象都能够成功回调后,all() 方法返回的promise对象才能执行成功的回调。

* 创建Promise对象:

    function creatPro (flag,oSucc,oFail) {
let pro = new Promise((resolve, reject)=>{
setTimeout(()=>{
if(flag){
resolve(oSucc)
}else{
reject(oFail)
}
},1000)
})
return pro
}

当所有异步对象都能执行成功回调时,all方法的成功回调返回一个所有对象成功回调数据的集合

    let p1 = creatPro(true,{status:1,msg:"异步成功1"},{status:0,msg:"异步失败1"});
let p2 = creatPro(true,{status:1,msg:"异步成功2"},{status:0,msg:"异步失败2"});
let p3 = creatPro(true,{status:1,msg:"异步成功3"},{status:0,msg:"异步失败3"}); Promise.all([p1,p2,p3])
.then((res)=>{
console.log(res);
})
.catch((err)=>{
console.log(err);
})

* 当出现失败的异步操作时,则返回第一个失败的异步回调信息

    let p1 = creatPro(true,{status:1,msg:"异步成功1"},{status:0,msg:"异步失败1"});
let p2 = creatPro(false,{status:1,msg:"异步成功2"},{status:0,msg:"异步失败2"});
let p3 = creatPro(false,{status:1,msg:"异步成功3"},{status:0,msg:"异步失败3"});

控制台的结果为:{status: 0, msg: "异步失败2"}

Promise.race()   多异步操作,顾名思义,返回的为第一个执行完成的回调信息,无论是成功还是失败。

看的是执行的速度,谁快返回谁:

    function creatPro (flag,oSucc,oFail,timeout) {
let pro = new Promise((resolve, reject)=>{
setTimeout(()=>{
if(flag){
resolve(oSucc)
}else{
reject(oFail)
}
},timeout)
})
return pro
} let p1 = creatPro(true,{status:1,msg:"异步成功1"},{status:0,msg:"异步失败1"},5000);
let p2 = creatPro(false,{status:1,msg:"异步成功2"},{status:0,msg:"异步失败2"},1000);
let p3 = creatPro(true,{status:1,msg:"异步成功3"},{status:0,msg:"异步失败3"},500); Promise.race([p1,p2,p3])
.then((res)=>{
console.log(res);
})
.catch((err)=>{
console.log(err);
})

执行结果:{status: 1, msg: "异步成功3"}

一个简单的例子搞懂ES6之Promise的更多相关文章

  1. java线程间通信:一个小Demo完全搞懂

    版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程系列文章只是自己知识的总结梳理,都是最基础的玩意,已经掌握熟练的可以绕过. 一.从一个小Demo说起 上篇我们聊到了Java多线程的同步 ...

  2. 跨站脚本功攻击,xss,一个简单的例子让你知道什么是xss攻击

    跨站脚本功攻击,xss,一个简单的例子让你知道什么是xss攻击 一.总结 一句话总结:比如用户留言功能,用户留言中写的是网页可执行代码,例如js代码,然后这段代码在可看到这段留言的不同一户的显示上就会 ...

  3. 用一个简单的例子来理解python高阶函数

    ============================ 用一个简单的例子来理解python高阶函数 ============================ 最近在用mailx发送邮件, 写法大致如 ...

  4. Spring-Context之一:一个简单的例子

    很久之前就想系统的学习和掌握Spring框架,但是拖了很久都没有行动.现在趁着在外出差杂事不多,就花时间来由浅入深的研究下Spring框架.Spring框架这几年来已经发展成为一个巨无霸产品.从最初的 ...

  5. 关于apriori算法的一个简单的例子

    apriori算法是关联规则挖掘中很基础也很经典的一个算法,我认为很多教程出现大堆的公式不是很适合一个初学者理解.因此,本文列举一个简单的例子来演示下apriori算法的整个步骤. 下面这个表格是代表 ...

  6. 扩展Python模块系列(二)----一个简单的例子

    本节使用一个简单的例子引出Python C/C++ API的详细使用方法.针对的是CPython的解释器. 目标:创建一个Python内建模块test,提供一个功能函数distance, 计算空间中两 ...

  7. fitnesse - 一个简单的例子(slim)

    fitnesse - 一个简单的例子(slim) 2017-09-30 目录1 编写测试代码(Fixture code)2 编写wiki page并运行  2.1 新建wikiPage  2.2 运行 ...

  8. Struts2的配置和一个简单的例子

    Struts2的配置和一个简单的例子 笔记仓库:https://github.com/nnngu/LearningNotes 简介 这篇文章主要讲如何在 IntelliJ IDEA 中使用 Strut ...

  9. 一个简单的例子了解states

    在大规模的配置管理工作中,我们要编写大量的states.sls文件.top.sls是states系统的入口文件,它负责指定哪些设备调用哪些states.sls文件.statse的默认工作目录是在/sr ...

随机推荐

  1. (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 通用的星星类已经完成了,下面我们来实现具体的变长和缩短道具. 变 ...

  2. HTML中锚点的使用

    说到锚点,我们也许会需要稍微的思考一下,什么是锚点? 官方的答案是这样的: 那么你可能就会有下面的疑问,锚点能做什么啊? 回答就是,锚点可以理解为一个标记,一个用于而且便于寻找的标记.常用于网页制作的 ...

  3. Java中怎么简单的使用正则表达式?

    对于正则表达式,我通常的认识就是通过一些陌生的奇怪的符号就可以完成很复杂事件的好帮手!实际上正则表达式确实是这方面的好助手,接下来让我们一起认识一下Java中怎么使用正则表达式吧. 初见Pattern ...

  4. Andriod的国际化-android学习之旅(五十八)

    android资源国际化

  5. SIM900A设备在保加利亚无法正常使用GPRS问题

    1.      SIM900A设备在保加利亚GPRS功能无法正常使用 我们一款手持设备采用SIM900A模块,在发货之前测试正常,但到了保加利亚,客户发现无法正常上网,我们技术支持反馈的邮件反馈的现象 ...

  6. Android进阶(五)在Eclipse中关联Gson源码

    1)获得相应的jar包gson-2.2.4-sources.jar与gson-2.2.4-javadoc.jar. 2)在libs目录下新建src包和docs包,将相应jar包放入相应文件夹内. 3) ...

  7. Chapter 2 User Authentication, Authorization, and Security(10):创建包含数据库

    原文出处:http://blog.csdn.net/dba_huangzj/article/details/39473895,专题目录:http://blog.csdn.net/dba_huangzj ...

  8. 多线程爬虫Miner

    多线程爬虫Miner 需要配置项:1.URL包含关键字.2.存储方式:DB-数据库存储;FILE-文件存储.3.爬取页面最大深度.4.下载页面线程数.5.分析页面线程数.6.存储线程数. ------ ...

  9. (一)php的基本知识和一些注意点

    注意:任何程序,包括php,在运行时都在内存中进行,php代码需要被读取到内存中才能执行. [php的运行方式] 1.通过服务器(例如apache)调用. 2.通过命令行调用(不需要服务器参与,因为没 ...

  10. (NO.00003)iOS游戏简单的机器人投射游戏成形记(五)

    上一篇我们建立了机器人物理对象,下面我们来看看对应的逻辑代码. 进入Xcode,新建Robot和Arm类,分别继承于CCNode和CCSprite类.代码全部留空,后面再实现. 我们再看一下这个机器人 ...