Promise的笔记

promise

我相信在前端的学习过程中“promise”的问题一直“拿捏”着大部分人的痛点。
首先,让我们回顾一下这些年遇到的Promise 常见面试问法:

1、了解 Promise 吗?
2、Promise 解决的痛点是什么?
3、Promise 解决的痛点还有其他方法可以解决吗?如果有,请列举。
4、Promise 如何使用?
5、Promise 常用的方法有哪些?它们的作用是什么?
6、Promise 在事件循环中的执行过程是怎样的?
7、Promise 的业界实现都有哪些?
8、能不能手写一个 Promise 的 polyfill。

这些问题,如果你都能 hold 住,那么面试官基本认可你了。带着上面这些问题,我们往下看。

一、概念

什么是promise?

Promise英文翻译过来意为承诺,许诺。它的作用就像中文意思一样,是一种许诺。

Promise是异步编程的一种解决方案,从语法上讲,Promise是一个对象,可以获取异步操作的消息。
比较官方的解释是这样说的:

Promise 对象是一个代理对象(代理一个值),被代理的值在Promise对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象。

有点难理解吧!
我们在编辑器中执行一下看下promise的底层
在这里插入图片描述
这么一来就看着明白一些了,Promise是一个构造函数,自身带有all、reject、resolve方法,原型上有then、catch等方法。这么说用Promise new出来的对象肯定就有then、catch方法喽!(稍后再说这些方法!)

二、目的

知道了promise的概念以后就衍生出了它是用来干什么的呢?

主要用于异步计算;
可以将异步操作队列化按照期望的顺序执行,返回自己想要的结果;
可以再对象之间传递和操作promise,帮助我们处理队列 ;

我们要知道的是promise有三个状态

  • pending【待定】初始状态
  • fulfilled 【实现】操作成功
  • rejected 【被否决】操作失败

三、为什么要使用promise

1、解决异步

我们都知道js是单线程执行代码,导致js的很多操作都是异步执行(ajax)的,以下是解决异步的几种方式:

  1. 回调函数(定时器)。
  2. 事件监听。
  3. 发布/订阅。
  4. Promise对象。(将执行代码和处理结果分开)
  5. ES7的async/await。

2、为了解决回调地狱问题
回调地狱:发送多个异步请求时,每个请求之间相互都有关联,会出现第一个请求成功后再做下一个请求的情况。我们这时候往往会用嵌套的方式来解决这种情况,但是这会形成”回调地狱“。如果处理的异步请求越多,那么回调嵌套的就越深。出现的问题:

  1. 代码逻辑顺序与执行顺序不一致,不利于阅读与维护。
  2. 异步操作顺序变更时,需要大规模的代码重构。
  3. 回调函数基本都是匿名函数,bug追踪困难
const request = url => {
    return new Promise((resolve,reject) => {
        $.get(url,params => {
            resolve(params)
        });
    });
};
​
request(url).then(params1 => {
    return request(params1.url);   
}).then(params2 => {
    return request(params2.url);
}).then(params3 => {
    console.log(params3);
}).catch(err => throw new Error(err));

四、Promise的用法

在promise中有几个方法:

  1. then的用法:then中传了两个参数,第一个对应resolve的回调,第二个对应reject的回调
p.then((data) => {
            console.log('resolved',data);
        },(err) => {
            console.log('rejected',err);
        }
    );
  1. atch方法:捕捉promise错误函数,和then函数参数中rejected作用一样,处理错误,由于Promise抛出错误具有冒泡性质,能够不断传递,会传到catch中,所以一般来说所有错误处理放在catch中,then中只处理成功的,同时catch还会捕捉resolved中抛出的异常
p.then((data) => {
    console.log('resolved',data);
})
.catch((err) => {
    console.log('rejected',err);
});
  1. all方法:Promise.all([promise1,promise2])——参数是对象数组。以慢为准,等数组中所有的promise对象状态为resolved时,该对象就为resolved;只要数组中有任意一个promise对象状态为rejected,该对象就为rejected
let p = Promise.all([Promise1, Promise2])

p.then((data) => {
    //都成功才表示成功
})
.catch((err) => {
    //有一个失败,则都失败
});
  1. race方法:Promise.race([promise1,promise2])——参数是对象数组。以快为准,数组中所有的promise对象,有一个先执行了何种状态,该对象就为何种状态,并执行相应函数
function racePromise(time){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(time);
        },time)
    })
}
var startDate = Date.now();
Promise.race([
    racePromise(5),
    racePromise(50),
    racePromise(500),
]).then(function(values){
    console.log(values);5
})

以上就是Promise中常用的几个方法

总结

为了便于理解 Promise,大家除了要多加练习以外,最好的方式是能够将Promise的机制与现实生活中的例子联系起来,这样才能真正得到消化。
我们可以把 Promise 比作一个保姆,家里的一连串的事情,你只需要吩咐给他,他就能帮你做,你就可以去做其他事情了。
Promise 这么多概念,初学者很难一下子消化掉,那么我们可以采取强制记忆法,强迫自己去记住使用过程。

  1. 首先初始化一个 Promise 对象,可以通过两种方式创建, 这两种方式都会返回一个 Promise 对象。
    new Promise(fn)
    Promise.resolve(fn)
  2. 然后调用上一步返回的 promise 对象的 then 方法,注册回调函数。
    then 中的回调函数可以有一个参数,也可以不带参数。如果 then 中的回调函数依赖上一步的返回结果,那么要带上参数。比如
new Promise(fn)
    .then(fn1(value){
        //处理value
    })
  1. 最后注册 catch 异常处理函数,处理前面回调中可能抛出的异常。

通常按照这三个步骤,你就能够应对绝大部分的异步处理场景。用熟之后,再去研究 Promise 各个函数更深层次的原理以及使用方式即可。

上面的内容希望各位看官多做练习,熟练的掌握Promise 的使用与原理,在遇到promise的问题时可以从容面对。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值