Promise是ES6原生提供的一个用来传递异步消息的对象。它减少了传统ajax金字塔回调,可以将异步操作以同步操作的流程表达出来使得代码维护和可读性方面好很多。

Promise的状态:

既然是用来传递异步消息的那肯定就会有异步消息的状态;所以promise提供了3种状态:pending(进行中),resolved(已完成或者称 fulfilled),rejected(失败)。不同的是Promise不会受外界影响,只有异步操作结果才能决定当前是哪种状态,任何其他非异步操作都不能改变。所以当状态发生改变了,即一个异步操作完成了就不会再变了。所以Promise对象的状态改变只有两种可能:①从pending---->resolved;②从pending---->rejected。只要这两种情况中的其中一种完成了就不会再发生改变了。即使对Promise对象添加回调函数也会得到这个结果。这里就跟事件Event不同了,Event是错过了这次监听,再去监听的时候是得不到结果的。

虽然Promise使得异步操作流程变得简单,但有时候它的优点也是它的缺点。比如当Promise建立时就会立即执行进入pending状态因为无法当前状态所以就无法取消Promise,只有异步操作才能改变。而且如果不设置回调函数的话Promise内部报错是不会反应到外部的。

在执行new Promise时浏览器会同步执行Promise构造函数中的方法,初始状态为pending,并从这个初始状态到resolved(fulfilled)或rejected状态的转换。一旦达到这两个其中之一的状态promise的状态就稳定了,是最终状态无法转换。

根据Promise规范,then或catch即使未显式指定返回值,它们也总是默认返回一个新的fulfilled状态的promise对象。

上一小段代码:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ES6 Promise</title>
</head>
<body>
<script>
function asyncFn() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("执行异步操作。。。。。");
resolve("执行异步操作成功将数据通过resolve方法返回");
}, 1000);
});
}
asyncFn().then( data => {
console.log(data); //得到的就是Promise中resolve方法传递过来的数据
});
</script>
</body>
</html>

我们可以看到代码可以正常执行:

这里demo代码中Promise构造函数接受一个函数作为参数,其中该函数分别接收resolve和reject这两个参数。如果Promise中异步操作成功,则resolve方法将Promise对象状态从pending变成resolved。如果失败则将pending变成rejected。

Promise API-->  all、race:

all方法:

all方法接收一个数组参数,里面的值最终都返回Promise对象。数组里面的异步操作都是并行执行的,当数组里的异步操作都执行完了才会进入到then中并将数组中的异步操作的数据返回。

all方法特别适合处理依赖多个异步请求的场景。当最后一个异步请求处理完成时返回所有异步请求结果

demo代码:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ES6 Promise</title>
</head>
<body>
<script>
function asyncFn1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("执行异步操作asyncFn1。。。。。");
resolve("执行异步操作asyncFn1成功将数据通过resolve方法返回");
}, 1000);
});
}
function asyncFn2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("执行异步操作asyncFn2。。。。。");
resolve("执行异步操作asyncFn2成功将数据通过resolve方法返回");
}, 1000);
});
}
function asyncFn3() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("执行异步操作asyncFn3。。。。。");
resolve("执行异步操作asyncFn3成功将数据通过resolve方法返回");
}, 1000);
});
}
Promise.all([asyncFn1(),asyncFn2(),asyncFn3()]).then( data => {
console.log(data); //得到的就是数组中的异步操作的数据
}); </script>
</body>
</html>

race方法:

race方法接收的也是一个数组参数,数组中元素也是Promise对象;返回的是执行最快的那个异步操作,其实从字面上的意思我们也可以看出来race就是赛跑的意思。

race适合多个异步请求中取最快那个异步请求场景;同时发送多个异步请求,只要一个请求成功那么就以该Promise做为最终状态并返回其值。其中对于状态稳定的Promise(fulfilled或rejected状态),哪个排第一,将返回哪个。

demo代码:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ES6 Promise</title>
</head>
<body>
<script>
function asyncFn1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("执行异步操作asyncFn1。。。。。");
resolve("执行异步操作asyncFn1成功将数据通过resolve方法返回");
}, 1000);
});
}
function asyncFn2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("执行异步操作asyncFn2。。。。。");
resolve("执行异步操作asyncFn2成功将数据通过resolve方法返回");
}, 2000);
});
}
function asyncFn3() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("执行异步操作asyncFn3。。。。。");
resolve("执行异步操作asyncFn3成功将数据通过resolve方法返回");
}, 3000);
});
}
Promise.race([asyncFn1(),asyncFn2(),asyncFn3()]).then( data => {
console.log(data); //得到的就是Promise中resolve方法传递过来的数据
}); </script>
</body>
</html>

这里只返回了最快的那个异步操作数据,但是asyncFn2和asyncFn3并没有停止是因为在数组中异步操作是并行的而且Promise构造函数执行的时候会先执行构造函数中的操作。

Promise原型的方法:

Promise原型只有Promise.prototype.then和Promise.prototype.catch。then方法让我们可以非常方便的使用链式调用;同时then可以接受两个回调,第一个是处理成功的回调,第二个是处理失败的回调。

demo如下:

 function asyncFn4() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("执行异步操作asyncFn4。。。。。");
resolve("执行异步操作asyncFn4成功将数据通过resolve方法返回");
}, 3000);
});
}
asyncFn4().then(res => {
10   console.log("处理成功的回调......");
console.log(res);
}, rejected => {
console.log("处理失败的回调。。。" + rejected);
});

catch用于捕获异常,无论是抛出的异常还是reject掉的异常都会被catch捕获。

我们对上面的代码做点小改动:

 function asyncFn4() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("执行异步操作asyncFn4。。。。。");
resolve("执行异步操作asyncFn4成功将数据通过resolve方法返回");
}, 3000);
});
}
asyncFn4().then(res => {
console.log("处理成功的回调......");
console.log(res);
}, rejected => {
console.log("处理失败的回调。。。" + rejected);
}).catch(err => {
console.log('catch到的异常,无论是Promise内部报错还是reject掉的异常都会被catch捕获')
});

then语句的onRejected回调并不能捕获onFulfilled回调内抛出的错误,其后的catch却可以捕获抛出的错误回调。

ES6中Promise对象个人理解的更多相关文章

  1. 阿里前端测试题--关于ES6中Promise函数的理解与应用

    今天做了阿里前端的笔试题目,原题目是这样的 //实现mergePromise函数,把传进去的数组顺序先后执行,//并且把返回的数据先后放到数组data中 const timeout = ms => ...

  2. ES6的promise对象研究

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

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

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

  4. 谈谈 ES6 的 Promise 对象

    https://segmentfault.com/a/1190000002928371 前言 开篇首先设想一个日常开发常常会遇到的需求:在多个接口异步请求数据,然后利用这些数据来进行一系列的操作.一般 ...

  5. 对es6中Promise和async的理解

    Promise var promise = new Promise((resolve,reject)=>{ resolve(value); //reject(value) }); //promi ...

  6. ES6的promise对象应该这样用

    ES6修补了一位Js修真者诸多的遗憾. 曾几何时,我这个小白从js非阻塞特性的坑中爬出来,当我经历了一些回调丑陋的写法和优化的尝试之后,我深深觉得js对于多线程阻塞式的开发语言而言,可能有着其太明显的 ...

  7. 对于ES6中Promise的个人见解

    1.js中常见的异步 JavaScript可以响应用户的一些异步交互,比如单击鼠标和按键盘等操作. let button = document.getElementById("btn&quo ...

  8. ES6 中 Promise

    在说Promise之前我们先简单说一下什么是同步异步? 同步(Sync):所谓同步,就是发出一个功能调用时,在没有得到结果之前,该调用就不返回或继续执行后续操作. 异步(Async):异步与同步相对, ...

  9. 浅谈Javascript中Promise对象的实现

    https://segmentfault.com/a/1190000000684654 What? Promise是CommonJS的规范之一,拥有resolve.reject.done.fail.t ...

随机推荐

  1. SoapUI实践:自动化测试、压力测试、持续集成

    因为项目的原因,前段时间研究并使用了 SoapUI 测试工具进行自测开发的 api.下面将研究的成果展示给大家,希望对需要的人有所帮助. SoapUI 是什么? SoapUI 是一个开源测试工具,通过 ...

  2. 搭建php环境的几种方法

    对于想学习php开发初学者来说,先要学习搭建php开发环境,因为要做php开发,搭建一个能够运行php网站的服务器环境是第一步,传统的php环境软件非常复杂,好在很多公司开发了一键搭建php安装环境, ...

  3. 从ThoughtWorks 2017技术雷达看微软技术

    ThoughtWorks在每年都会出品两期技术雷达,这是一份关于技术趋势的报告,它比起一些我们能在市面上见到的其他各种技术行情和预测报告,更加具体,更具可操作性,因为它不仅涉及到新技术大趋势,比如云平 ...

  4. OC语言的Block与Protocol(协议)

    Block ● Block封装了一段代码,可以在任何时候执⾏行 ● Block可以作为函数参数或者函数的返回值,⽽而其本⾝身又可以带输⼊入参数或返回值. ● 苹果官⽅方建议尽量多⽤用block.在多线 ...

  5. BootStra相关脚本引用说明

    先看一个简单的模板(DOCTYPE是html5的文档类型) <!DOCTYPE html> <html lang="zh-CN"> <head> ...

  6. 制作支持 BIOS+UEFI 的 U 盘 grub2+bootmgr 引导 + deepin_recovery + deepin_iso + win_pe

    网盘下载:https://pan.baidu.com/s/1c2GXPo0 U盘为 FAT32,MBR分区表 1.下载:U盘grub2+bootmgr引导2017.12.6.2.7z 2.解压到 U盘 ...

  7. Serverless无服务应用架构纵横谈

    Serverless无服务应用架构纵横谈 一.Serverless是啥 自从互联网兴起以来,Server就成了网络的核心部件.所以围绕Server的生意圈,也发展得如火如荼. 从最早的电信托管,到虚拟 ...

  8. 自己动手编写IOC框架(二)

    万事开头难,上篇已经起了一个头,之后的事情相对就简单了.上次定义了框架所需的dtd也就是规定了xml中该怎么写,有哪些元素.并且我们也让dtd和xml绑定在了一起,使dtd对xml的格式进行校验,并且 ...

  9. CS Round#49 C Max Substring

    Max Substring Time limit: 1000 msMemory limit: 256 MB   You are given a string S. Find a string T th ...

  10. day8、 显示Linux路由表、各列信息

    要用到的命令是 route route 命令    显示和设置Linux路由表 -A:设置地址类型: -C:打印将Linux核心的路由缓存: -v:详细信息模式: -n:不执行DNS反向查找,直接显示 ...