前端高频面试题 promise 初级篇

前端高频面试题 promise
ps:绝大部分资料来源于网络,只是添加了一些更容易理解的话,方便我这种小白快速记忆面试。。。

promise概述

Promise是跟随es6出来对异步回调地狱的一种很好的解决方案。

那么什么是回调地狱?

如果没有promise,我们想发送一个异步请求需要

// 请求 代表 一个异步网络调用。
// 请求结果 代表网络请求的响应。
请求1(function(请求结果1){
    处理请求结果1
})

看起来还行是吧,但是现在来了,我们需要用上一个请求结果来发送下一个请求。然后再再再再发送请求,于是,回调地狱来了。

请求1(function(请求结果1){
    请求2(function(请求结果2){
        请求3(function(请求结果3){
            请求4(function(请求结果4){
                请求5(function(请求结果5){
                    请求6(function(请求结果3){
                        ...  //此处省略五百个请求,你慌不慌?
                    })
                })
            })
        })
    })
})

于是,一大堆问题来了,例如:
·代码臃肿。
·可读性差。
·耦合度过高,可维护性差。
·代码复用性差。
·容易滋生 bug,且不容易发现
·只能在回调里处理异常。

那咋整啊?于是promise来了

promise三种状态
//Promise是异步的一种解决方案,他有三种状态:
pending    //等待/进行中
fulfilled 	//完成
rejected	//失败/错误
promise用法

首先初始化一个 Promise 对象,可以通过两种方式创建, 这两种方式都会返回一个 Promise 对象。

方法1、new Promise(fn)
方法2、Promise.resolve(fn)

然后调用上一步返回的 promise 对象的 then 方法,注册回调函数。

then 中的回调函数可以有一个参数,也可以不带参数。如果 then 中的回调函数依赖上一步的返回结果,那么要带上参数。比如

    new Promise(fn)
    .then(fn1(value){
        //处理value
    })

学废了? 来个小题目试试?

以下程序代码运行后结果是什么?

new Promise(function(resolve, reject) {
  console.log(1);
  resolve('success');
  console.log(2);
  reject('error');
  console.log(3);
}).then(function(value) {
  console.log('then', value);
}).catch(function(err) {
  console.err('error:', err);
});











提示:promise是异步的





答案:

1
2
3
then success

再来一个

const promise = new Promise((resolve, reject) => {
  console.log(1)
  resolve()
  console.log(2)
})
promise.then(() => {
  console.log(3)
})
console.log(4)
















答案

1
2
4
3

promise状态变化

Promise必须存在一种状态(pending或fulfilled或rejected)。如果为pending状态,那么可以转换到其他的两个状态;如果为fulfilled状态,那么必须有一个值,并且值和状态不可改变;如果为rejected状态,那么必须有一个原因,并且状态和原因不可改变。

目前只研究透了这么一丢丢,后续玩明白了继续更新。

还有,那什么是resolve和reject呢?以及使用方法

首先实例化Promise时需要传入一个函数excutor作为参数,并且在Promise构造函数执行时同步执行。

var p = new Promise(function(resolve,reject){
             var timer = setTimeout(function(){
                 console.log('执行操作1');
             },1000);
         });

我们可以看到1s后在控制台输出相应的结果,这就说明在实例化过程中,作为参数的excutor函数也会执行。

从上面的实例中我们看到,excutor函数还有两个参数resolve和reject,其实这两个参数也是函数,在excutor执行时被调用,下面我们具体来谈谈resolve和reject的用法。
———————————————————————————

当我们在excutor函数中调用resolve方法时,Promise的状态就变成fulfilled,即操作成功状态,还记得上面Promise.prototype上面的then和catch方法吗?当Promise状态为fullfilled状态时执行then方法里的操作,注意了,then方法里面有两个参数onfulfilled(Promise为fulfilled状态时执行) 和onrejected(Promise为rejected状态时执行),步骤如下:

1,实例化Promise(new Promise(function(resolve,reject)))

2,用Promise的实例调用then方法

具体来看下面的例子:

resolve方法

var p = new Promise(function (resolve, reject) {
            var timer = setTimeout(function () {
                console.log('执行操作1');
                resolve('这是数据1');
            }, 1000);
        });
        p.then(function (data) {
            console.log(data);
            console.log('这是成功操作');
        });

简单的理解就是调用resolve方法,Promise变为操作成功状态(fulfilled),执行then方法里面onfulfilled里的操作。其实then里面的函数就是我们平时所说的回调函数,只不过在这里只是把它分离出来而已。我们可以看到控制台上的输出结果如下所示:

执行操作1
这是数据1
这是成功操作

reject方法
看了上面的实例,我相信应该也很容易理解reject方法了,就是调用reject方法后,Promise状态变为rejected,即操作失败状态,此时执行then方法里面onrejected操作,上面我们提到了then方法有两个参数,一种是Promise状态为fulfilled时执行(onfullfilled),一种是Promise状态为rejected时执行(onrejected),其实就是类似于jquery里的hover方法里面的两个参数一样,来看看下面的例子:

var p = new Promise(function (resolve, reject) {
          var flag = false;
          if(flag){
            resolve('这是数据2');
          }else{
            reject('这是数据2');
          }
        });
        p.then(function(data){//状态为fulfilled时执行
            console.log(data);
            console.log('这是成功操作');
        },function(reason){ //状态为rejected时执行
            console.log(reason);
            console.log('这是失败的操作');
        });

我们可以看到这样的结果

这是数据2
这是失败的操作

cash方法
我们注意到除了then方法外,Promise原型上还有另外一个叫catch的方法,那么这个方法的作用是什么呢?其实跟then方法中的第二个参数一样,就是在Promise状态为rejected时执行,then方法捕捉到Promise的状态为rejected,就执行catch方法里面的操作,下面用catch方法改写上面reject用法里面的例子,如下所示:

var p = new Promise(function (resolve, reject) {
            var flag = false;
            if(flag){
              resolve('这是数据2');
            }else{
              reject('这是数据2');
            }
          });
          p.then(function(data){
              console.log(data);
              console.log('这是成功操作');
          }).catch(function(reason){
              console.log(reason);
              console.log('这是失败的操作');
          });

执行结果和上面reject用法的例子一样。

这是数据2
这是失败的操作

resolve,reject参见 _夜渐凉

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值