1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > JavaScript Promise详解 resolve() reject() then() catch() finally()(包含习题)

JavaScript Promise详解 resolve() reject() then() catch() finally()(包含习题)

时间:2021-02-06 10:59:26

相关推荐

JavaScript Promise详解 resolve() reject() then() catch() finally()(包含习题)

Promise

Promise是个十分优雅的词,他的中文含义是承诺、约定的意思,在古今中外都有非常多的和“承诺”相关的历史故事、寓言故事和名言名句,那么今天我们就来一起了解下JavaScript中的Promise吧!

文章目录

Promise一、Promise基础特点一: `promise`的状态一旦改变就无法更改特点二:`promise`实例内部本身是同步执行的 二、`promise`的静态方法`Promise.resolve()``Promise.reject()` 三、`Promise`的实例方法1、`Promise.then()`2、`Promise.catch()`3、`Promise.finally()` 总结

一、Promise基础

promise是ES6新增的引用类型,可以通过 new 操作符来实例化。创建新的promise需要传入执行器(executor)函数作为参数。

我们new一个Promise实例:

const promise = new Promise(function(resolve, reject) {resolve(value);});

Promise对象有以下两个特点。

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

特点一:promise的状态一旦改变就无法更改

我们看一个例子就可以清晰了解到promise的状态特点:

const p = new Promise((resolve,reject) => {resolve()reject()})const p2 = new Promise((resolve,reject) => {reject()resolve()})console.log(p)//Promise {<fulfilled>: undefined}console.log(p2)//Promise {<rejected>: undefined}

所以我们总结promise的第一个特点: promise的状态一旦改变就无法更改

特点二:promise实例内部本身是同步执行的

在初始化promise时,执行器已经改变了每个promise的状态。我们知道执行器函数是同步执行的。我看看一个例子:

console.log('a')setTimeout(function(){console.log('f')}, 200)const p = new Promise(resolve => {console.log('b')resolve('g')console.log('c')})setTimeout(function(){console.log('e')}, 0)console.log('d')//答案:/*abcdef*/

如果看不懂执行js执行机制可以先阅读我上一篇文章【JavaScript】JS执行机制微任务和宏任务

所以我们总结promise的第二个特点:promise本身是同步执行的

二、promise的静态方法

这里先介绍两个最基本的静态方法,下一篇文章会带来:raceallSettledAllany的拓展静态方法

Promise.resolve()

通过调用Promise.resolve()方法我们可以实例化一个解决的Promise

下面两个实例的结果实际上是一样的:

const p1 = new Promise(resolve => {resolve()})const p2 = Promise.resolve()console.log(p1)//Promise {<fulfilled>: undefined}console.log(p2)//Promise {<fulfilled>: undefined}console.log(p1==p2)

Promise.reject()

Promise.resolve()一样,Promise.reject()实例化一个拒绝状态的Promise并抛出错误。

下面两个实例的结果实际上是一样的:

const p1 = new Promise(reject => {reject()})const p2 = Promise.reject()console.log(p1)//Promise {<rejected>: undefined}console.log(p2)//Promise {<rejected>: undefined}

三、Promise的实例方法

1、Promise.then()

Promise.then()接收最多两个参数:onResolvedonRejected。两个参数都是可选的,如果提供的话promise会进入“fulfilled”和“rejected”状态时执行。

我看来看一下例子:

const p1 = new Promise((resolve,reject )=> {setTimeout(function(){resolve('我是resolve,成功状态');}, 2000);});const p2 = new Promise((resolve,reject )=> {setTimeout(function(){reject ('我是reject,失败状态');}, 2000);});p1.then((res)=>{console.log(res)},(err)=>{console.log(err)}) //我是resolve,成功状态p2.then(null,(err)=>{console.log(err)})// 我是reject,失败状态

因为期约状态只有一次所以onResolvedonRejected这两个操作一定是互斥的。

传给.then()的任何非函数类型的参数都会被静默忽略。所以我们一般只提供一个参数,那么在另一个状态的参数上我们传入null。可以有助于避免在内存中创建多余的对象

我们根据特性:传给.then()的任何非函数类型的参数都会被静默忽略做一道习题:

Promise.resolve(1).then(2).then(Promise.resolve(3)).then(console.log)//第一个then和第二个then中传入的都不是函数,一个是数字,一个是对象,因此发生了透传,将resolve(1) 的值直接传到最后一个then里。所以输出结果为:1

2、Promise.catch()

catch方法用于给Promise添加拒绝处理程序。这个方法只接收一个参数,事实上他就是.then的一个语法糖,调用它就相当于上文中的:

Promise.then(null,(err)=>{ console.log(err)})

根据(事实上他就是.then的一个语法糖)这一个特点,我们再来结合Promise特点一(promise的状态一旦改变就无法更改) 和 .then的特点(Promise.then()接收最多两个参数:onResolved和onRejected)做一道综合练习题:

Promise.reject('err!!!').then((res) => {console.log('success', res)}, (err) => {console.log('error', err)}).catch(err => {console.log('catch', err)})// 在这道题中,错误直接被then的第二个参数捕获了,所以就不会被catch捕获了,输出结果为:'error' 'error!!!'

3、Promise.finally()

finally()方法用于指定不管Promise对象最后状态如何,都会执行的操作。该方法是 ES 引入标准的。

promise.then((result) => {/* ···*/}) .catch((error) => {/* ···*/}) .finally(() => {/* ···*/});

下面是一个例子,服务器使用 Promise 处理请求,然后使用finally方法关掉服务器。

server.listen(port) .then(function() {/* ... */ }) .finally(server.stop);

finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。

我们来看一道习题了解finally的特性:

Promise.resolve('1').then(res => {console.log(res)}).finally(() => {console.log('finally')})Promise.resolve('2').finally(() => {console.log('finally2')return '我是finally2返回的值'}).then(res => {console.log('finally2后面的then函数', res)})/*结果: 1finally2finallyfinally2后面的then函数 2*/

finally本质上是then方法的特例。

总结

那么最后总结一下promise的几个小特点:

特点一:promise的状态一旦改变就无法更改特点二:promise实例内部本身是同步执行的特点三:Promise.then()接收最多两个参数:onResolvedonRejected。两个参数都是可选的,如果提供参数的话promise会进入“fulfilled”和“rejected”状态时执行。特点四:传给.then()的任何非函数类型的参数都会被静默忽略特点五:Promise.catch()只接收一个参数。事实上他就是.then的一个语法糖 相当于:Promise.then(null,(err)=>{ console.log(err)})只是我们不用传递第一个null参数了特点六:Promise.finally()方法不管Promise对象最后的状态如何都会执行特点七:finally()方法的回调函数不接受任何的参数,也就是说你在.finally()函数中是无法知道Promise最终的状态是resolved还是rejected的特点八:finally()它最终返回的默认会是一个上一次的Promise对象值,不过如果抛出的是一个异常则返回异常的Promise对象。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。