Promise大厂面试题-持续更新中...

632 阅读1分钟

1.(阿里)promise原理

2.(阿里)promise.then()两个参数用法;如果有两个参数后面又有catch,reject会走哪一个?从代码角度说一下。

let p1 = new Promise( (resolve, reject) => {
    console.log('没有resolve');
    reject('reject抛出错误')
}).then(res => {
    console.log('then 第一个回调函数', res);
}, rea => {
    console.log('then 第二个回调函数', rea);
}).catch(err => {
    console.log('catch捕获', err);
})
//没有resolve
//then 第二个回调函数 reject抛出错误

结论:如果Promise.then()有两个参数后面又有catch,reject会走then的第二个回调函数。

3.(腾讯)promise和async/await的优先顺序。

4.(腾讯)手写Promise简易实现

const PENDING = 'PENDING',
      FULFILLED = 'FULFILLED',
      REJECTED = 'REJECTED';


class myPromise {
    constructor(executor) {
        this.status = PENDING;
        this.value = undefined;
        this.reason = undefined;
        this.onResolveCallbacks = [];
        this.onRejectedCallbacks = [];
        const resolve = (value) => {
            if (this.status === PENDING) {
                this.status = FULFILLED;
                this.value = value;
                this.onResolveCallbacks.forEach((fn) => fn())
            }
        }
        const reject = (reason) => {
            if (this.status === PENDING) {
                this.status = REJECTED;
                this.reason = reason;
                this.onRejectedCallbacks.forEach((fn) => fn())
            }
        }
        try { //把实例化的promise中throw的错误归入reject中
            executor(resolve, reject);
        } catch (e) {
            reject(e);
        }

    }
    then(onFulfilled, onRejected) {
        if (this.status === FULFILLED) {
            onFulfilled(this.value);
        }
        if (this.status === REJECTED) {
            onRejected(this.reason);
        }
        if (this.status === PENDING) {
            // 处理异步函数  订阅
            this.onResolveCallbacks.push(() => {
                onFulfilled(this.value);
            })
            this.onRejectedCallbacks.push(() => {
                onRejected(this.value);
            })
        }
    }

}

5.代码实现Promise串行.

function runPromiseByQueue(promises) {
  promises.reduce(
    (previousPromise, nextPromise) => previousPromise.then(() => nextPromise()),
    Promise.resolve()
  )
}

const createPromise = (time, id) => () => {
  new Promise(resolve => {
    setTimeout(() => {
      console.log("promise", id);
      resolve();
    }, time)
  })
}

runPromiseByQueue([
  createPromise(3000, 1),
  createPromise(2000, 2),
  createPromise(1000, 3)
])

6.代码实现Promise.all.

Promise.all =  function(promises) {
    // promises 是可迭代对象,省略参数合法性检查
    return new Promise((resolve, reject) => {
        // Array.from 将可迭代对象转换为数组
        promises = Array.from(promises);
        if(promises.length === 0) {
            resolve([]);
        } else {
            let result = [];
            let index = 0;
            for(let i = 0; i < promises.length; i++) {
                // 考虑i可能是thenable对象也可能是普通值
                Promise.resolve(promises[i]).then(data => {
                    result[i] = data;
                    if(++index === promises.length) {
                        // 所有的promises状态都是fulfilled,promise.all返回的实例才变成fulfilled状态
                        resolve(result);
                    }
                }, err => {
                    reject(err);
                    return;
                })
            }
        }
    })
}

7.(头条)用promise.all实现一个promise.allSettled(具体是让失败了也输出结果)。

Promise.allSettled = function(promises) {
    return Promise.all(
    	Array.from(promises).map(p => Promise.resolve(p).then(
        	res => {
                return {
                    status: 'fulfilled',
                    value: res
                }
            },
            e => {
                return {
                    status: 'rejected',
                    reason: e
                }
            }
        ))
    )
}