Iwen's blog Iwen's blog
首页
  • 前端文章

    • JavaScript
    • Vue
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 小程序笔记
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • Linux
  • 学习
  • 面试
  • 心情杂货
  • 友情链接
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
复盘
关于

Iwen

不摸鱼的哥哥
首页
  • 前端文章

    • JavaScript
    • Vue
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 小程序笔记
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • Linux
  • 学习
  • 面试
  • 心情杂货
  • 友情链接
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
复盘
关于
  • Vue

  • Vue进阶

  • CSS

  • ES6

  • Base

  • Core

  • Array

  • Object

  • String

  • Async

  • Browser

  • Http

  • 性能优化

  • 正则

  • 经典总结

  • 设计模式

  • 数据结构

  • 算法

  • 手写

    • call、apply
    • 实现bind函数
    • instanceOf
    • new 原理及模拟实现
    • 防抖、节流
    • 发布订阅模式
    • 深拷贝
    • Promise A+
    • Promise 进阶
      • Promise.resolve
      • Promise.reject
      • Promise.finally
      • Promise.all
      • Promise.race
      • Promise实现网络超时判断
    • Array-prototype-map
    • Array-prototype-filter
    • Array-prototype-reduce
    • 并发请求
    • 继承
    • JSON 字符串
  • TypeScript

  • 复盘
  • 手写
Mr.w
2020-11-29

Promise 进阶

# Promise 进阶

# Promise.resolve

这里就不考虑参数是thenable对象了,那么参数有两种情况:

  1. Promise 实例,直接返回
  2. 不是 Promise 实例,返回一个新的 Promise 对象,状态为FULFILLED
Promise.resolve = function(param){
    if (param instanceof MyPromise) {
        return param
    }
    return new MyPromise((resolve, reject) => resolve(param))
}
1
2
3
4
5
6

# Promise.reject

Promise.reject 中传入的参数会作为一个 reason 原封不动地往下传, 实现如下:

Promise.reject = function(param){
    return new MyPromise((resolve, reject) => reject(param))
}
1
2
3

# Promise.finally

无论当前 Promise 是成功还是失败,调用 finally 之后都会执行 finally 中传入的函数,并且将值原封不动的往下传。

Promise.finally = function(callback) {
    this.then(value => {
        return Promise.resolve(callback()).then(() => {
            return value;
        })
    }, error => {
        return Promise.resolve(callback()).then(() => {
            throw error;
        })
    })
}
1
2
3
4
5
6
7
8
9
10
11

# Promise.all

返回一个 promise 对象,只有当所有 promise 都成功时返回的 promise 状态才成功,需要注意的点是:

  1. 数组成员不为promise,则直接进行resolve()
  2. 所有的 promise 状态变为 FULFILLED,返回的 promise 状态才变为 FULFILLED。
  3. 一个 promise 状态变为REJECTED,返回的 promise 状态就变为REJECTED。
  4. 在任何情况下,Promise.all 返回的 promise 的完成状态的结果都是一个数组

具体实现如下:

Promise.all = function(promises){
    return new MyPromise((resolve, reject) => {
        let result = [];
        let len = promises.length;
        
        if (len === 0) {
            return resolve(result)
        }

        for (let i = 0; i < len; i++) {
            Promise.resolve(promises[i]).then(res => {
                result[i] = res
                if (i == len - 1) { // 最后一个
                    resolve(result)
                }
            }).catch(err => {
                reject(err)
            })
        }
    })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# Promise.race

race 的实现相比之下就简单一些,只要有一个 promise 执行完,直接 resolve 并停止执行。

Promise.race = function(promises){
    return new MyPromise((resolve, reject) => {
        let len = promises.length;
        if (len === 0) return
        for (let i = 0; i < len; i++) {
            Promise.resolve(promises[i]).then(res => {
                resolve(res)
                return
            }).catch(err => {
                reject(err)
                return
            })
        }
    })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

到此为止,一个完整的 Promise 就被我们实现完啦。从原理到细节,我们一步步拆解和实现,希望大家在知道 Promise 设计上的几大亮点之后,也能自己手动实现一个 Promise,让自己的思维层次和动手能力更上一层楼!

# Promise实现网络超时判断

使用Promise实现网络请求超时判断,超过三秒视为超时。 借助的是Promise.race这个方法:

const uploadFile = () => {
    return Promise.race([
        uploadFilePromise(),
        uploadFileTimeout(3000)
    ])
}

function uploadFilePromise() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('OK')
        }, 3100)
    })
}

function uploadFileTimeout() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('Time out ~~')
        }, 3000)
    })
}

uploadFile().then((res) => {
    console.log(res)
}).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
Promise A+
Array-prototype-map

← Promise A+ Array-prototype-map→

最近更新
01
flex布局页面自适应滚动条问题
12-28
02
前后端分离开发请求接口跨域如何携带cookie的问题
12-28
03
怎么实现div长宽比固定width-height4比3
12-28
更多文章>
Theme by Vdoing | Copyright © 2017-2022 Iwen | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式