Simonzhangs' blog Simonzhangs' blog
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • JS设计模式总结
  • 《Vue》
  • 《React》
  • 《TypeScript 从零实现 axios》
  • TypeScript
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • apple music
  • extension
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Simonzhangs

前端学习探索者
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • JS设计模式总结
  • 《Vue》
  • 《React》
  • 《TypeScript 从零实现 axios》
  • TypeScript
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • apple music
  • extension
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • HTML

  • CSS

  • JavaScript文章

    • 33个非常实用的JavaScript一行代码
    • new命令原理
    • ES5面向对象
    • ES6面向对象
    • 多种数组去重性能对比
    • JS随机打乱数组
    • 判断是否为移动端浏览器
    • 将一维数组按指定长度转为二维数组
    • 防抖与节流函数
    • JS获取和修改url参数
    • 比typeof运算符更准确的类型判断
    • 常见面试题

      • 四级文件(测试)
      • 原型与原型链
      • JS数据类型
      • call、apply、bind
      • JavaScript运行机制
      • promise
        • 一、手写promise
          • 01.Promise特点
          • 02.ES6 promise 用法详解
          • then链式操作
          • reject用法
          • catch方法
          • all方法
          • race方法
          • 03.手写Promise
        • 二、闭包
        • 三、原型
        • 四、call apply
        • 五、Webpack
      • JS中在new的时候发生了什么
  • 学习笔记

  • 前端
  • JavaScript文章
  • 常见面试题
simonzhangs
2022-03-27
目录

promise

前端工作面试问题 (opens new window)

# 一、手写promise

参考文章:

Promise不会??看这里!!!史上最通俗易懂的Promise!!! (opens new window)

阮一峰大神文章:Promise对象 (opens new window)

面试官对不起!我终于会了Promise...(一面凉经泪目) (opens new window)

# 01.Promise特点

ECMAscript 6 原生提供了 Promise 对象。

  • Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。

  • promise有三种状态: pending(等待态),fulfiled(成功态),rejected(失败态) ;

  • 状态一旦改变,就不会再变。创造promise实例后,它会立即执行。

  • 这个promise可以解决异步的问题,本身不能说promise是异步的

优点:

  • 将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数,落入回调地狱;
  • Promise 对象提供统一的接口,使得控制异步操作更加容易

缺点:

  • 无法取消 Promise,一旦新建它就会立即执行,无法中途取消;
  • 如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部;
  • 当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

# 02.ES6 promise 用法详解

Promise是一个构造函数,本身有all、reject、resolve 常用方法,原型上有 then、catch 等方法。

Promise构造函数接收一个参数:函数,该函数需要传入两个参数:

  • resolve: 异步操作执行成功后的回调函数;
  • reject: 异步操作执行失败后的回调函数。
const p = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        console.log('执行完成!');
        resolve('异步操作成功啦!')
    },2000);
})
1
2
3
4
5
6

# then链式操作

p.then((data) => {
    console.log(data);
})
.then((data) => {
    console.log(data);
})
.then((data) => {
    console.log(data);
});
1
2
3
4
5
6
7
8
9

# reject用法

const p = new Promise((resolve,reject)=>{
    setTimeout(function(){
        const num = Math.ceil(Math.random()*10);
        if(num<=5){
            resolve(num);
        }else{
            reject('数字大于5')
        }
    },2000);
});

p.then((data)=>{
    console.log('resolved',data);
},(err)=>{
    console.log('rejected',err);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

把Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。

then方法可以接受两个参数:

  • 第一个对应resolve的回调;
  • 第二个对应reject的回调,所以我们能够分别拿到他们传过来的数据。

# catch方法

catch其实它和then的第二个参数一样,用来指定reject的回调。

p.then((data)=>{
    console.log('resolved',data)
}).catch((erro)=>{
    console.log('rejected',erro);
})
1
2
3
4
5

此外,在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。

Promise 对象的错误具有"冒泡"性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个 catch 语句捕获。

# all方法

谁跑的慢,以谁为准执行回调。all接收一个数组参数,里面的值最终都算返回Promise对象。

Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。

const Promise1 = new Promise(function(resolve,reject){})
const Promise2 = new Promise(function(resolve,reject){})
const Promise3 = new Promise(function(resolve,reject){})

const p = Promise.all([Promise1,Promise2,Promise3])

p.then(function(){
    //三个都成功则成功
},function(){
    //只要有失败,则失败
})
1
2
3
4
5
6
7
8
9
10
11

有一个场景是很适合用这个的,一些游戏类的素材比较多的应用,打开网页时,预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完后,我们再进行页面的初始化。

# race方法

谁跑的快,以谁为准执行回调。


function requestImg(){
    const p =new Promise((resolve,reject)=>{
        const img = new Image();
        img.onload = function(){
            resolve(img);
        }
        img.src = 'path'
    });
    return p;
}

function timeout(){
    const p = new Promise((resolve,reject)=>{
        setTimeout(() => {
            reject('图片请求超时');
        }, 2000);
    });
    return p;
}

Promise.race([requestImg(),timeout()])
.then((data)=>{
    console.log(data);
})
.catch((err)=>{
    console.log(err);
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 03.手写Promise

封装一系列内置方法,需要包括:

  • 捕获错误的方法 catch()
  • 解析全部方法 all()
  • 竞赛 race()
  • 生成一个成功的 promise resolve()
  • 生成一个失败的 promise reject()

# 二、闭包

# 三、原型

# 四、call apply

# 五、Webpack

参考文章:

🔥【万字】透过分析 webpack 面试题,构建 webpack5.x 知识体系 (opens new window)​

编辑 (opens new window)
#promise
上次更新: 2022/05/17, 21:50:47
JavaScript运行机制
JS中在new的时候发生了什么

← JavaScript运行机制 JS中在new的时候发生了什么→

最近更新
01
一些有意思的类比
06-16
02
the-super-tiny-compiler解析
06-06
03
计算机编译原理总概
06-06
更多文章>
Theme by Vdoing | Copyright © 2021-2022
蜀ICP备2021023197号-2
Simonzhans | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
  • 飙升榜
  • 新歌榜
  • 云音乐民谣榜
  • 美国Billboard榜
  • UK排行榜周榜