时间:2021-05-28
promise用了这么多年了,一直也没有系统整理过。今天整理整理promise的相关东西,感兴趣的可以一起看一看。我尽量用更容易理解的语言来剖析一下promise
我准备分两篇文章来说明一下promise
一篇来理解和使用promise(本篇) 另一篇来从promise使用功能的角度来剖析下promise的源码(下一篇)
我的理解是:实现让我们用同步的方式去写异步代码的一种技术。是异步解决方案的一种。
他可以将多个异步操作进行队列化,让它们可以按照我们的想法去顺序执行。
那么,Promise之前有没有其他的异步解决方案。肯定是有的,常见的有callback回调函数以及事件。
那Promise有啥优势,我认为Promise功能更为强大,且能让我们代码写的更为清晰
首先,我们先来了解一些Promise的基本概念
Promise一共有3中状态,分别是Pending(进行中)、Resolved(已完成,又称Fulfilled)和Rejected(已失败)
状态的改变只可能从Pending转------>Resolved,或者从Pending------->Rejected。并且状态一旦发生改变,就不会再更改了。而触发状态发生改变的,只有异步操作的结果。结果为成功 触发状态变更为 Resolved, 结果失败或者中途发生错误,则会触发状态变更为 Rejected
Promise是一个构造函数,故通过new Promise()可以实例化出来一个Promise对象
new Promise()时,接受一个函数作为参数,且这个函数,有两个参数,分别是resolve,reject。 而resolve和 reject也是两个函数。他们由JavaScript引擎提供,不用自己部署。
每一个被实例化出来的promise实例,都有.then() 和 .catch() 两个方法。且这两个方法的调用支持链式操作
好,了解完概念,我们看看Promise的基本用法
首先,如何实例化一个promise对象
const promise = new Promise((resolve, reject) => { setTimeout(() => { if () { resolve(res) } else { reject(err) } }, 100)})上图中,通过new Promise() 实例化了一个promise实例,注意:new Promise()方法中的函数是一个立即执行函数,即,在new Promise()的一瞬间就会被执行。函数内代码是同步代码。
resolve和reject用于返回异步操作的结果,当使用resolve()时,promise状态会由Pending—>Resolved, 并将异步的正确结果返回。当使用reject()时,promise状态由Pending---->Rejected,并将错误信息返回
再看这个对象如何接收返回的结果
promise.then((res) => { console.log(res)}).catch((err) => { console.log(err)})上图中,.then的回调函数 和 .catch的回调函数分别用来接收resolve()返回的正确信息和reject返回的错误信息。
下面我们来详细看下.then() 和 .catch()
.then() 函数
then()函数是Promise实例的一个方法,他的作用是为Promise实例添加状态改变时的回调函数
它存在以下特点
下面,我们重点来分析下第2,3,4,5
function getData(url) { return new Promise((resolve, reject) => { setTimeout(() => { if (url) { resolve({ code: 200, message: 'ok', data: 123 }) } else { reject(new Error('缺少url')) } }, 100) })}getData('http://', method: 'post'}).then((res) => { console.log(res)}).catch((err) => { console.log(err)})Promise.all()可以并行执行多个Promise(), 并返回一个新的Promise实例
var p = Promise.all([p1, p2, p3]); // p1,p2,p3为3个Promise实例Promise.all()的参数不一定是数组,只要具有Iterator接口的数据都可以(Iterator是一个遍历器,我这里就不做过多介绍,感兴趣的可以自己去官网看看)。但是参数遍历后返回的成员必须必须是Promise对象(如上面的,p1,p2,p3都必须是Promise对象,如果不是,则会先调用Promise.resolve(p1)将他转化为Promise实例)
那么,Promise.all()返回的Promise实例的状态是如何定义的。
如上图, 最后一个成员(上图中7返回的promise实例)的状态是在3.5s后才变更为Resolved,故.then()的resolve回调在3.5s后才执行
function getData (data) { return new Promise((resolve, reject) => { setTimeout(() => { if (data === 6) { reject(new Error('请求发生错误了')) } else { resolve(data) } }, data * 500) })}const promises = [2,4,6,8].map((item) => { return getData(item)})Promise.all(promises).then((res) => { console.log('请求成功') console.log(res)}).catch((err) => { console.log('请求失败') console.log(err)})// 3s后输出请求失败Error: 请求发生错误了上图可以看出,当我们改用 2,4,6,8去得到promise成员时,第3s得时候 发生了错误,此时,Promise.all()返回得Promise实例得状态立刻变更为Rejected,catch()的回调立即触发。故输出错误
Promise.race()和Promise.all()的作用是一样的,都是并发处理多个Promise实例,并返回一个新的实例。
而区别在于,两者返回的新的Promise实例的状态改变的时机不同。
Promise.all是 所有Promise子成员状态都变为Resolved, 新的Promise实例状态才会变成Resolved。中途如果有任何一个子成员状态变成了Rejected,新的Promise实例的状态就会立刻变为Rejected
Promise.race是 只要子成员中,有任何一个的状态发生了变化(不管是变成Resolved还是Rejected),那么返回的新的Promise实例的状态也会立刻发生变化,而变化的状态就是那个子成员所变化的状态。
function getData (data) { return new Promise((resolve, reject) => { setTimeout(() => { if (data === 6) { reject(new Error('请求发生错误了')) } else { resolve(data) } }, data * 500) })}const promises = [2,4,6,8].map((item) => { return getData(item)})Promise.race(promises).then((res) => { console.log('请求成功') console.log(res)}).catch((err) => { console.log('请求失败') console.log(err)})// 1s后输出请求成功2上图可以看出,1s后 第一个子成员状态变更为Resolved,那么返回的新Promise实例状态也立马变更为Resolved,故1s后.then()的resolve回调执行。输出请求成功.
最后,我们来说一说前面用到了的Promise.resolve()吧
前面我们说到过 Promise.resolve可以返回一个状态是Resolved的Promise对象。没错,其实它等同于
new Promise((resolve, reject) => { resolve()})当Promise.resolve()有参数时,会返回一个Promise对象的同时,将参数做作为then()resolve回调的参数返回(当参数是thenable对象除外,后面会将)。主要有以下几种情况
1、参数是一个Promise对象时
将会直接返回这个参数,不做任何更改
2、参数是thenable对象时,(即,存在.then()方法的对象),如下
let obj= { then: function(resolve, reject) { resolve('我是thenable对象'); }};此时,Promise.resolve(obj) 会返回一个Promise对象,并且调用obj的then()方法,哎,这里注意了,这个.then()并不是 新Promise对象的.then() , obj的then()会立即执行,可不代表 新的Promise对象的then() 的回调也会执行, 还记得吗,我们前面说的Promise对象的then()的回调执行的条件是这个Promise对象的状态发生变化了才会执行。
let obj= { then: function(resolve, reject) { console.log(123) }}; let p1 = Promise.resolve(obj);p1.then(function(value) { console.log('成功') console.log(value); // 42});// 输出123从上图可以看出来,立即执行了obj.then(),但Promise的then的回调并没有被执行
会返回一个Promise实例,并将参数作为.then()的resolve回调的参数返回
如,Promise.resolve(‘123') 等价于
new Promise((resolve, reject) => { resolve('123')})返回了一个Resolved状态的Promise对象,但是.then()的resolve回调没有参数。
new Promise((resolve, reject) => { resolve()}).then((res) => { console.log(res)})// 输出undefinedPromise.resolve()
Promise.reject() 也是返回一个Promise对象,只是这个对象的状态是Rejected
至于参数的用法和Promise.resolve()完全一样,唯一的区别是没有thenable参数一说,也就是说有参数时,参数不论哪种情况,都会被当做catch()的回调参数返回。也就是说参数没有前面1,2,3种的区别。大家可以去试试,我就不过多说明了。
到此这篇关于ES6学习教程之Promise用法详解的文章就介绍到这了,更多相关ES6之Promise用法内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了es6中Promise对象基本功能与用法。分享给大家供大家参考,具体如下:Promise是异步编程的一种解决方案,解决——回调函数和事件ES6规定
去年6月份,ES2015正式发布(也就是ES6,ES6是它的乳名),其中Promise被列为正式规范。作为ES6中最重要的特性之一,我们有必要掌握并理解透彻。本
JavaScript的Promise.all()Promise是JavaScript异步编程的一种解决方案,在ES6中引入。通过Promise.all()可以实
本文实例讲述了ES6中异步对象Promise用法。分享给大家供大家参考,具体如下:回忆一下ES5中的怎么使用异步方法//es5中的异步回调letajax=fun
问题原因:IE一些低版本的浏览器对于ES6语法不支持Promise是es6语法里为了解决异步函数多重嵌套的问题(回调地狱)说明:或许你并不没有使用Promise