当前位置:   article > 正文

面试问 Promise 不会?超级详细的手写Promise原理,带你一步一步写出一个自己的 Promise_promise原理 面试

promise原理 面试

Promise 原理 及其 实现


首先要实现 Promise 就要让我们了解它具体功能

let p1 = new Promise((resolve)=>{
    resolve(2)
})
console.log(p1);

let p2 = new Promise((resolve,reject)=>{
    reject('shibai')
})

console.log(p2);

let p3 = new Promise((resolve,reject)=>{
    err
})

console.log(p3);

let p4 = new Promise((resolve,reject)=>{
})

console.log(p4);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

输出结果:

image-20220312142353182

可以看到我们的主要功能是:

一开是 Promise 的状态为 pending 等于未处理状态

1、执行了resolve,Promise状态会变成fulfilled

2、执行了reject,Promise状态会变成rejected

3、Promise只以第一次为准,第一次成功就永久fulfilled,第一次失败就永远状态为rejected

4、Promise中有throw 或者出现语法错误的话,就相当于执行了reject

image-20220301234936199

接下来就按着这个思路一步一步的实现

一、实现resolve和reject

1、resolve与reject

首先注意首次调用 new Promise 时应该是初始化状态,

并传进一个可含有 resolve,与 reject 两个参数 的函数

参数在构造函数内调用实现对应功能,

并且注意:函数使用箭头函数的形式来确保对应 this 为该实例对象

class MyPromise{
    constructor(excutor){
        // 初始化参数
        this.initValue()
        // 执行对应方法
        excutor(this.resolve,this.reject)
    }

    // 初始化函数,初始状态与值
    // 使用箭头函数使this指向实例对象
    initValue = () =>{
        this.PromiseState = 'pending'
        this.PromiseResult = null
    }

    // resolve 方法
    resolve = (value) =>{
        this.PromiseState = 'fulfilled'
        this.PromiseResult = value
    }

    // reject 方法
    reject = (reason) =>{
        this.PromiseState = 'rejected'
        this.PromiseResult = reason
    }
}

//  测试代码
let p1 = new MyPromise((resolve,reject)=>{
    resolve('成功')
})
console.log(p1);  //  MyPromise { PromiseState: 'fulfilled', PromiseResult: '成功' }

let p2 = new MyPromise((resolve,reject)=>{
    reject('失败')
})
console.log(p2);  // MyPromise { PromiseState: 'rejected', PromiseResult: '失败' }
  • 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
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

输出结果:

image-20220312143823214

2. 状态不可变

上述代码有一个问题

let p1 = new MyPromise((resolve,reject)=>{
      resolve('成功')
      reject('失败')
    })
    console.log(p1);  //  MyPromise { PromiseState: 'rejected', PromiseResult: '失败' }
  • 1
  • 2
  • 3
  • 4
  • 5

为什么会这样呢?

实际上在对于已经执行过的 resolvereject 我们就应该终止执行,而不是再执行下一次 resolvereject

代码实现起来也很简单:

	// resolve 方法
    resolve = (value) =>{
 /*--------------------------------------代码变更----------------------------------------------------------------*/
        // 加这一个判断即可
        if(this.PromiseState !== 'pending') return 
        this.PromiseState = 'fulfilled'
        this.PromiseResult = value
    }

    // reject 方法
    reject = (reason) =>{
 /*--------------------------------------代码变更----------------------------------------------------------------*/
        if(this.PromiseState !== 'pending') return 
        this.PromiseState = 'rejected'
        this.PromiseResult = reason
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

再看看结果:

let p1 = new MyPromise((resolve,reject)=>{
      resolve('成功')
      reject('失败')
    })
    console.log(p1);  //  MyPromise { PromiseState: 'fulfiiled', PromiseResult: '成功' }
  • 1
  • 2
  • 3
  • 4
  • 5

3. throw

Promise 的执行者(executor)和 promise 的处理程序(handler)周围有一个“隐式的 try..catch”。如果发生异常,它(译注:指异常)就会被捕获,并被视为 rejection 进行处理。

故我们要让执行错误 或者 手动抛错的语法,也变成 reject 执行

加个 “隐式的 try..catch

constructor(excutor){
    // 初始化参数
    this.initValue()
    // 执行对应方法
    try {
        excutor(this.resolve,this.reject)
    } catch (err) {
        this.reject(err.message)
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

看看输出结果:

let p1 = new MyPromise((resolve,reject)=>{
    throw Error('错误')
})
console.log(p1);   // MyPromise {PromiseState: "rejected", PromiseResult: "错误"}
let p3 = new MyPromise((resolve,reject)=>{
    promise()  //  一个不存在的函数,会报错
})
console.log(p3); // MyPromise {PromiseState: "rejected", PromiseResult: "promise is not defined"}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

image-20220312145225062

二、实现 then

Promisethen 相当于将 resolve 或者 reject 的结果,在一个 成功回调 ,一个 失败回调 中使用

看下日常使用的代码:

// 马上输出 ”成功“
const p1 = new Promise((resolve, reject) => {
    resolve('成功')
}).then(res => console.log(res), err => console.log(err))

// 1秒后输出 ”失败“
const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject('失败')
    }, 1000)
}).then(res => console.log(res), err => console.log(err))

// 链式调用 输出 200
const p3 = new Promise((resolve, reject) => {
    resolve(100)
}).then(res => 2 * res, err => console.log(err))
  .then(res => console.log(res), err => console.log(err))

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

可以总结出这几个知识点

  • then接收两个回调,一个是成功回调,一个是失败回调

  • 当Promise状态为fulfilled执行成功回调,为rejected执行失败回调

  • 如resolve或reject在定时器里,则定时器结束后再执行then

  • then支持链式调用,下一次then执行受上一次then返回值的影响

下面咱们就一步一步地去实现他吧

1. 实现then

// then 方法回调
then = (onFulfilled,onRejected)=>{
    // 首先确保传进来的是函数
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
    onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}

    //判断promise的状态执行对应回调
    if(this.PromiseState === 'fulfilled'){
        // 若是成功则执行成功的回调,传入成功的值
        onFulfilled(this.PromiseResult)
    }
    else if(this.PromiseState === 'rejected'){
        // 若是成功则执行成功的回调,传入成功的值
        onRejected(this.PromiseResult)
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

让我们看看结果:

let p1 = new MyPromise((resolve,reject)=>{
    resolve("成功")
}).then(res=>{
    console.log(res); // 成功
})
  • 1
  • 2
  • 3
  • 4
  • 5

2. 定时器情况

上面我们已经实现了then的基本功能。那如果是定时器情况呢?

就好比下面情况

// 1秒后输出 ”成功“
const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('成功')
    }, 1000)
}).then(res => console.log(res), err => console.log(err))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我们要如何实现,1秒后输出成功呢?

实际上,我们不能控制 .then then方法的调用的时间,但是我们可以在每次调用时

then 方法传的两个回调函数保存起来,待定时间到时后,我们再执行回调

我们要如何判断,什么时候该执行回调呢?

其实很简单!

当定时器结束前,Promise 状态都是 pending

当定时器结束后,会调用 resolve 或者 reject 来改变对应 Promise 的状态

所以当我们监测到状态发生变化时,即定时器结束了调用了 resolve 或者 reject

只需要在调用时判断存起来的回调函数是否存在,存在就将回调函数提出来,并执行即可

下面是实现代码:

constructor(excutor){
    // 初始化参数
    this.initValue()
    // 执行对应方法
    try {
        excutor(this.resolve,this.reject)
    } catch (err) {
        this.reject(err.message)
    }
    /*-----------------------------------代码改动部分--------------------------------------------------------*/
    // 初始化回调函数
    this.onFulfilledSync = []
    this.onRejectedSync = []
}

// resolve 方法
resolve = (value) =>{
    if(this.PromiseState !== 'pending') return 
    this.PromiseState = 'fulfilled'
    this.PromiseResult = value
    /*-----------------------------------代码改动部分--------------------------------------------------------*/
    // 判断是否有then执行回调
    while(this.onFulfilledSync.length){
        this.onFulfilledSync.shift()(this.PromiseResult)
    }
}

// reject 方法
reject = (reason) =>{
    if(this.PromiseState !== 'pending') return 
    this.PromiseState = 'rejected'
    this.PromiseResult = reason
    // 判断是否有then执行回调
    /*-----------------------------------代码改动部分--------------------------------------------------------*/
    while(this.onRejectedSync.length){
        this.onRejectedSync.shift()(this.PromiseResult)
    }
}

// then 方法回调
then = (onFulfilled,onRejected)=>{
    // 首先确保传进来的是函数
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
    onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}

    //判断promise的状态执行对应回调
    if(this.PromiseState === 'fulfilled'){
        // 若是成功则执行成功的回调,传入成功的值
        onFulfilled(this.PromiseResult)
    }
    else if(this.PromiseState === 'rejected'){
        // 若是成功则执行成功的回调,传入成功的值
        onRejected(this.PromiseResult)
    }
    /*-----------------------------------代码改动部分--------------------------------------------------------*/
    // 多加了一层判断当定时还没结束时,状态就是pending,那么将回调函数保存起来
    else if(this.PromiseState === 'pending')
        this.onFulfilledSync.push(onFulfilled)
    	this.onRejectedSync.push(onRejected)
}

  • 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
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

下面看看加了定时器的输出结果吧:

let p1 = new MyPromise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('一秒后输出成功')
    },1000)
}).then(res=>{
    console.log(res); // 一秒后输出成功
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3. 链式调用

then支持链式调用,下一次then执行受上一次then返回值的影响,给大家举个例子:

// 链式调用 输出 200
const p3 = new Promise((resolve, reject) => {
    resolve(100)
}).then(res => 2 * res, err => console.log(err))
    .then(res => console.log(res), err => console.log(err))

// 链式调用 输出300
const p4 = new Promise((resolve, reject) => {
    resolve(100)
}).then(res => new Promise((resolve, reject) => resolve(3 * res)), err => console.log(err))
    .then(res => console.log(res), err => console.log(err))

// 非promise 链式调用手动抛出错误(类似reject)
new Promise((resolve,reject)=>{
    resolve('失败')
}).then(res=>{
    throw res
}).then(res=>{console.log(res);},err=>{console.log(err);}) // err 失败回调 处输出'失败'
// 非promise 链式调用正常返回值
new Promise((resolve,reject)=>{
    reject('失败')
}).then(res=>{},err=>err)
    .then(res=>{console.log(res);},err=>{console.log(err);}) // res 成功回调 处输出'失败'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

从上方例子,我们可以获取到几个知识点:

  • 1、then方法本身会返回一个新的Promise对象
  • 2、如果返回值是promise对象,返回值为成功,新promise就是成功将调用下个then的成功回调
  • 3、如果返回值是promise对象,返回值为失败,新promise就是失败将调用下个then的失败回调
  • 4、如果返回值非promise对象,新promise对象就是成功,值为此返回值
  • 5、如果返回值非promise对象,并手动抛出错误,新promise对象就是失败,值为此错误信息

咱们知道then是Promise上的方法,那如何实现then完还能再then呢?

很简单,then执行后返回一个Promise对象就行了,就能保证then完还能继续执行then:

代码实现:

// then 方法回调
then = (onFulfilled,onRejected)=>{
    // 首先确保传进来的是函数
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
    onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}
/*----------------------------------------代码改变区域---------------------------------------------------*/
    // 创建一个then返回的Promise
    const thenPromise = new MyPromise((resolve,reject)=>{
        // 创建 then 回调函数的执行函数
        const resultPromise = cb =>{
            // 执行then回调函数,并用try,catch隐式捕捉错误
            try {
                const result = cb(this.PromiseResult)
                // 如果返回的结果还是promise
                if(result instanceof MyPromise){
                    // 要判断它的状态,到底是resolve 还是 reject 只有调用它自身的then方法才得知
                    // 将要返回的resolve,reject,作为它then的回调,这样就能保持一致的状态
                    result.then(resolve,reject)
                }
                // 如果不是返回的promise
                else{
                    resolve(result)
                }
            } catch (err) {
                // 抛出的错误,在此捕获并reject掉
                reject(err.message)
            }
        }
        // 开始执行then回调
        if(this.PromiseState === 'fulfilled'){
            resultPromise(onFulfilled)
        }
        else if(this.PromiseState === 'rejected'){
            resultPromise(onRejected)
        }
        else if(this.PromiseState === 'pending'){
            this.onFulfilledSync.push(onFulfilled)
            this.onRejectedSync.push(onRejected)
        }

    })

    // 调用then后返回处理果的结果
    return thenPromise
/*----------------------------------------代码改变区域---------------------------------------------------*/
}
  • 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
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

看看最终实现的效果吧:

let p1 = new MyPromise((resolve,reject)=>{
    resolve(2)})
.then(res=> res * 2)
.then(res=>{console.log(res)})  //  输出 4  将 res * 2 返回后再输出

let p2 = new MyPromise((resolve,reject)=>{
    resolve(2)})
.then(res=> {throw Error('失败')})  //  这里在第一个then里手动reject  
.then(res=>{},err=>{console.log(err);})  // 最后也会第二个失败回调里输出 失败

let p3 = new MyPromise((resolve,reject)=>{
    resolve(2)})
.then(res=>new MyPromise((resolve,reject)=>reject('promise失败')))  // 通过第一个then返回promise来reject
.then(res=>{},err=>{console.log(err);})  // 最后也会第二个失败回调里输出 romise失败
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

image-20220312162537996

当你真的搞懂后,就会明白为什么第一个then里成功回调里抛出错误,会在第二个then里失败回调输出

4. 微任务

看过js执行机制的兄弟都知道,then方法是微任务,啥叫微任务呢?

不理解的可以看之前写的一篇介绍 Promise微任务

其实不知道也不要紧,我通过下面例子让你知道:

const p = new Promise((resolve, reject) => {
    console.log(1)
    resolve(2)
}).then(res => console.log(res), err => console.log(err))

console.log(3)

输出顺序是 1 3 2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

因为then微任务的缘故,故在script执行完后才会执行微任务

所以输出 1 —> 3 —> 2

那我们只需要让 resultPromise函数异步执行就可以了

const resultPromise = cb =>{
    /*------------------------------------在此加上定时器----------------------------------------------------*/
    setTimeout(()=>{
        // 执行then回调函数,并用try,catch隐式捕捉错误
        try {
            const result = cb(this.PromiseResult)
            // 如果返回的结果还是promise
            if(result instanceof MyPromise){
                // 要判断它的状态,到底是resolve 还是 reject 只有调用它自身的then方法才得知
                // 将要返回的resolve,reject,作为它then的回调,这样就能保持一致的状态
                result.then(resolve,reject)
            }
            // 如果不是返回的promise
            else{
                resolve(result)
            }
        } catch (err) {
            // 抛出的错误,在此捕获并reject掉
            reject(err.message)
        }
    })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

看看输出结果:

const test4 = new MyPromise((resolve, reject) => {
    console.log('xxx');
    resolve(100)
}).then(res => {
    console.log(res);
    throw new Error('eee')
}, err => new MyPromise((resolve, reject) => resolve(3 * err)))
.then(res => console.log('成功', res), err => console.log('失败', err))

console.log('sss');

// xxx ---> sss ---> 100 ---> 失败 ,eee
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

三、最后总结

代码最终实现的模板

class MyPromise{
    constructor(excutor){
        // 初始化参数
        this.initValue()
        // 执行对应方法
        try {
            excutor(this.resolve,this.reject)
        } catch (err) {
            this.reject(err.message)
        }
        // 初始化回调函数
        this.onFulfilledSync = []
        this.onRejectedSync = []
    }

    initValue = () =>{
        this.PromiseState = 'pending'
        this.PromiseResult = null
    }

    // resolve 方法
    resolve = (value) =>{
        if(this.PromiseState !== 'pending') return 
        this.PromiseState = 'fulfilled'
        this.PromiseResult = value
        // 判断是否有then执行回调
        while(this.onFulfilledSync.length){
            this.onFulfilledSync.shift()(this.PromiseResult)
        }
    }

    // reject 方法
    reject = (reason) =>{
        if(this.PromiseState !== 'pending') return 
        this.PromiseState = 'rejected'
        this.PromiseResult = reason
        // 判断是否有then执行回调
        while(this.onRejectedSync.length){
            this.onRejectedSync.shift()(this.PromiseResult)
        }
    }

    // then 方法回调
    then = (onFulfilled,onRejected)=>{
        // 首先确保传进来的是函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
        onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}

        // 创建一个then返回的Promise
        const thenPromise = new MyPromise((resolve,reject)=>{
            // 创建 then 回调函数的执行函数
            const resultPromise = cb =>{
                setTimeout(()=>{
                    // 执行then回调函数,并用try,catch隐式捕捉错误
                    try {
                        // 调用cb(onFulfilled) // cb(onRejected)
                        const result = cb(this.PromiseResult)
                        //确保不是自身调用
                        if(result === thenPromise) throw new Error('不能调用自身')
                        // 如果返回的结果还是promise
                        if(result instanceof MyPromise){
                            // 要判断它的状态,到底是resolve 还是 reject 只有调用它自身的then方法才得知
                            // 将要返回的resolve,reject,作为它then的回调,这样就能保持一致的状态
                            result.then(resolve,reject)
                        }
                        // 如果不是返回的promise
                        else{
                            resolve(result)
                        }
                    } catch (err) {
                        // 抛出的错误,在此捕获并reject掉
                        reject(err.message)
                    }
                })
            }
            // 开始执行then回调
            if(this.PromiseState === 'fulfilled'){
                resultPromise(onFulfilled)
            }
            else if(this.PromiseState === 'rejected'){
                resultPromise(onRejected)
            }
            else if(this.PromiseState === 'pending'){
                this.onFulfilledSync.push(onFulfilled)
                this.onRejectedSync.push(onRejected)
            }

        })

        // 调用then后返回处理果的结果
        return thenPromise
    }
}
  • 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
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93

测试代码:

let p1 = new MyPromise((resolve,reject)=>{
    resolve(2)})
.then(res=> res * 2)
.then(res=>{console.log(res)}) // 4

let p2 = new MyPromise((resolve,reject)=>{
    resolve(2)})
.then(res=> {throw Error('失败')})
.then(res=>{},err=>{console.log(err);})  // 失败

//  链式加延迟调用
let p3 = new MyPromise((resolve,reject)=>{
    resolve(2)})
.then(res=>{
    return new MyPromise((resolve,reject)=>{
        setTimeout(()=>{resolve(res*2)},1000)
    })
})
.then(res=>{console.log(res);},err=>{console.log(err);})  //  4
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

如果你真的搞懂,那么这些你看着也不会有什么问题

最后感谢参考的三心大哥的文章:https://juejin.cn/post/6994594642280857630#heading-15

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/876505
推荐阅读
相关标签
  

闽ICP备14008679号