ES6中Promise对象个人理解

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对象。

上一小段代码:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>ES6 Promise</title>
 6 </head>
 7 <body>
 8     <script>
 9         function asyncFn() {
10             return new Promise((resolve, reject) => {
11                 setTimeout(() => {
12                     console.log("执行异步操作。。。。。");
13                     resolve("执行异步操作成功将数据通过resolve方法返回");
14                 }, 1000);
15             });
16         }
17         asyncFn().then( data => {
18             console.log(data); //得到的就是Promise中resolve方法传递过来的数据
19         });
20     </script>
21 </body>
22 </html>

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

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

Promise API-->  all、race:

all方法:

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

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

demo代码:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>ES6 Promise</title>
 6 </head>
 7 <body>
 8     <script>
 9         function asyncFn1() {
10             return new Promise((resolve, reject) => {
11                 setTimeout(() => {
12                     console.log("执行异步操作asyncFn1。。。。。");
13                     resolve("执行异步操作asyncFn1成功将数据通过resolve方法返回");
14                 }, 1000);
15             });
16         }
17         function asyncFn2() {
18             return new Promise((resolve, reject) => {
19                 setTimeout(() => {
20                     console.log("执行异步操作asyncFn2。。。。。");
21                     resolve("执行异步操作asyncFn2成功将数据通过resolve方法返回");
22                 }, 1000);
23             });
24         }
25         function asyncFn3() {
26             return new Promise((resolve, reject) => {
27                 setTimeout(() => {
28                     console.log("执行异步操作asyncFn3。。。。。");
29                     resolve("执行异步操作asyncFn3成功将数据通过resolve方法返回");
30                 }, 1000);
31             });
32         }
33         Promise.all([asyncFn1(),asyncFn2(),asyncFn3()]).then( data => {
34             console.log(data); //得到的就是数组中的异步操作的数据
35         });
36
37     </script>
38 </body>
39 </html>

race方法:

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

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

demo代码:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>ES6 Promise</title>
 6 </head>
 7 <body>
 8     <script>
 9         function asyncFn1() {
10             return new Promise((resolve, reject) => {
11                 setTimeout(() => {
12                     console.log("执行异步操作asyncFn1。。。。。");
13                     resolve("执行异步操作asyncFn1成功将数据通过resolve方法返回");
14                 }, 1000);
15             });
16         }
17         function asyncFn2() {
18             return new Promise((resolve, reject) => {
19                 setTimeout(() => {
20                     console.log("执行异步操作asyncFn2。。。。。");
21                     resolve("执行异步操作asyncFn2成功将数据通过resolve方法返回");
22                 }, 2000);
23             });
24         }
25         function asyncFn3() {
26             return new Promise((resolve, reject) => {
27                 setTimeout(() => {
28                     console.log("执行异步操作asyncFn3。。。。。");
29                     resolve("执行异步操作asyncFn3成功将数据通过resolve方法返回");
30                 }, 3000);
31             });
32         }
33         Promise.race([asyncFn1(),asyncFn2(),asyncFn3()]).then( data => {
34             console.log(data); //得到的就是Promise中resolve方法传递过来的数据
35         });
36
37     </script>
38 </body>
39 </html>

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

Promise原型的方法:

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

demo如下:

 1 function asyncFn4() {
 2    return new Promise((resolve, reject) => {
 3          setTimeout(() => {
 4              console.log("执行异步操作asyncFn4。。。。。");
 5              resolve("执行异步操作asyncFn4成功将数据通过resolve方法返回");
 6                 }, 3000);
 7          });
 8    }
 9 asyncFn4().then(res => {
10   console.log("处理成功的回调......");
11    console.log(res);
12}, rejected => {
13    console.log("处理失败的回调。。。" + rejected);
14 });

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

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

 1 function asyncFn4() {
 2    return new Promise((resolve, reject) => {
 3       setTimeout(() => {
 4          console.log("执行异步操作asyncFn4。。。。。");
 5          resolve("执行异步操作asyncFn4成功将数据通过resolve方法返回");
 6       }, 3000);
 7      });
 8 }
 9 asyncFn4().then(res => {
10     console.log("处理成功的回调......");
11     console.log(res);
12 }, rejected => {
13     console.log("处理失败的回调。。。" + rejected);
14 }).catch(err => {
15     console.log(‘catch到的异常,无论是Promise内部报错还是reject掉的异常都会被catch捕获‘)
16 });

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

时间: 2024-10-08 10:28:29

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

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

今天做了阿里前端的见识题目,原题目是这样的 //实现mergePromise函数,把传进去的数组顺序先后执行,//并且把返回的数据先后放到数组data中 const timeout = ms => new Promise((resolve, reject) => {setTimeout(() => {resolve();}, ms);}); const ajax1 = () => timeout(2000).then(() => {console.log('1');retur

谈谈 ES6 的 Promise 对象

前言 开篇首先设想一个日常开发常常会遇到的需求:在多个接口异步请求数据,然后利用这些数据来进行一系列的操作.一般会这样去写: $.ajax({ url: '......', success: function (data) { $.ajax({ // 要在第一个请求成功后才可以执行下一步 url: '......', success: function (data) { // ...... } }); } }); 这样的写法的原理是,当执行一些异步操作时,我们需要知道操作是否已经完成,所有当执行

ES6的promise对象应该这样用

ES6修补了一位Js修真者诸多的遗憾. 曾几何时,我这个小白从js非阻塞特性的坑中爬出来,当我经历了一些回调丑陋的写法和优化的尝试之后,我深深觉得js对于多线程阻塞式的开发语言而言,可能有着其太明显的缺点,而又无法忽略的是也正因为这一点,node.js处理并行的能力被人看作优点,在我看来,这其实有着些讽刺的意味,就好像踢足球时有的人总夸你腿短,所以频率快下盘稳好控球...好在js从出生以来就有一种独特的特质,就是模仿,对,就是模仿,模仿别人的优点来补足自己,同时保持自己的长处. ES6就是通过P

ES6 - promise对象

Promise的设计初衷 我们使用ajax请求数据,得到数据后再对数据进行操作,可是有时候,对得到的数据进行操作的过程中,可能又要用到ajax请求,这时,我们的代码就变成了这样: $.ajax({ success:function(res1){ //...请求B开始,B依赖A返回的数据 $.ajax({ sucess:function(res2){ //...请求C开始,C依赖B返回的数据 $.ajax({ sucess:function(res3){ } }); } }); } }); 这种写

浅谈Javascript中Promise对象的实现

https://segmentfault.com/a/1190000000684654 What? Promise是CommonJS的规范之一,拥有resolve.reject.done.fail.then等方法,能够帮助我们控制代码的流程,避免函数的多层嵌套.如今异步在web开发中越来越重要,对于开发人员来说,这种非线性执行的编程会让开发者觉得难以掌控,而Promise可以让我们更好地掌控代码的执行流程,jQuery等流行的js库都已经实现了这个对象,年底即将发布的ES6也将原生实现Promi

es6 之 promise 对象

异步编程 传统方案:事件 + 回调函数 ES6 的新方案:Promise 对象 Promise 异步操作有 3 种状态 pending: 进行中 resolved: 已完成 rejected: 已失败 Promise 异步操作的状态变化仅限下面两种方式 pending –> resolved pending –> rejected 创建一个 Promise 实例: promise 构造函数接收一个函数作为参数,并且这个函数有两个参数,这两个参数是也是两个函数,不过这两个函数由 JavaScri

ES6知识点-Promise对象

4.3Promise对象 4.3.1Promise概述 Promise是异步编程的一种解决方案. Promise是为了解决多重嵌套回调函数而提出的. 它不是新的语法功能,而是一种新的写法,允许将回调函数的嵌套,改成链式调用. Promise是一个对象,从它可以获取异步操作的消息. Promise提供统一的API,各种异步操作都可以用同样的方法进行处理. Promise有以下两个特点: 对象的状态不受外界影响.Promise对象代表一个异步操作,有三种状态:Pending(进行中).Resolve

ES6 的 Promise 对象

$.ajax({ url: '......', success: function (data) { $.ajax({ // 要在第一个请求成功后才可以执行下一步 url: '......', success: function (data) { // ...... } }); } }); 当执行一些异步操作时,我们需要知道操作是否已经完成,当执行完成的时候会返回一个回调函数,表示操作已经完成. 再继续进行下一个接口请求..... 回调函数的形式在实际的应用当中会有以下的缺点: 在需要多个操作的

ES6中对对象的扩展

ES6允许直接写入变量和函数作为对象的属性和方法.这样的书写更加简洁. ES6允许在对象中只写属性名,不写属性值.这时,属性值等于属性名所代表的变量. function f(x , y){ return {x ,y}; } f(1,2)// Object {x:1,y:2} function getPoint(){ var x=1; var y=10; return {x,y}; } getPoint()//{x:1,y:10} js语言定义对象的属性有两种方法.obj.foo=true;obj