从Promise结构到Promise实现

简介: nodejs面试时,会常常被问到promise的相关实现和原理,甚至还有现场写个Promise的实现。所以首先对Promise要有一定的了解。

nodejs面试时,会常常被问到promise的相关实现和原理,甚至还有现场写个Promise的实现。所以首先对Promise要有一定的了解。

Promise结构

let p = new Promise((resolve, reject) => {
  // doing something
  ... ... 
  resolve(result)  // 成功
  //reject(errmsg) // 失败
})
.then(result => { ... }, errmsg => { ... })
.catch(error => {... })
  • Promise有三种状态:pending,fulfilled,rejected
  • Promise是一个类,构造函数的参数是一个函数,函数接收的参数也是2个函数(reslove函数和reject函数)
  • resolve函数表示成功,传入的值会传给then方法的回调函数,reject函数表示失败
  • 有个then方法,有2个参数,第一个参数是成功之后执行的回调函数,第二个参数是失败之后的执行的回调函数;且then方法在resolve或reject执行之后才会执行
  • Promise支持链式调用

实现Promise

实现一个Promise类,需要以下内容:

1、状态:进行中,成功,失败;且状态转换只允许是:进行中-->成功;进行中-->失败

2、resolve和reject方法

3、then方法:参数为2个回调函数

4、执行方法:promise状态改变的方法

5、链式调用:每次then方法都返回一个新的Promise

class myPromise {
    static pending = 'pending';
    static fulfilled = 'fulfilled';
    static rejected = 'rejected';
​
    constructor(executor) {
        this.status = myPromise.pending;//初始状态为pending
        this.value = undefined; // 操作成功时返回值
        this.message = undefined; // 操作失败时返回值
​
        this.callbacks = [];
      // 绑定this防止执行时this指向对象改变
        executor(this._resolve.bind(this), this._reject().bind(this))
    }
   // 参数onFulFilled 是函数,成功时执行
   // 参数onRejected是函数,失败时执行
   // 不是then函数在状态改变后执行,而是then中的回调函数在状态改变后执行,所以then方法将回调当入队列中
    then(onFulFilled, onRejected) {
        return myPromise((nextResolve, nextRejected) => {
            this._handler({
                nextResolve,
                nextRejected,
                onFulFilled,
                onRejected
            })
        })
    }
​
    _resolve(value) {
        this.value = value;
        this.status = myPromise.fulfilled;// 状态设置为成功
​
        // 通知事件执行
        this.callbacks.forEach((cb) => { this._handler(cb) })
    }
​
    _reject(message) {
        this.message = message;
        this.status = myPromise.rejected; // 状态设置为失败
        // 通知事件执行
        this.callbacks.forEach((cb) => { this._handler(cb) })
    }
​
     _handler(callback) {
        const { onFulFilled, onRejected ,nextResolve, nextReject} = callback;
        if (this.status === myPromise.pending) {
            this.callbacks.push(callback);
            return;
        }
​
        if (this.status === myPromise.fulfilled) {
            // 传入存储的值
            // 未传入onFulfilled时,将undefined传入
            const nextValue = onFulfilled ? onFulfilled(this.value) : undefined;
            nextResolve(nextValue);
            return;
        }
​
        if (this.status === myPromise.rejected) {
            // 传入存储的错误信息
            // 同样的处理
            const nextMessage = onRejected ? onRejected(this.message) : undefined;
            nextResolve(nextMessage);
        }
    }
}
​

面试题

1、题目1:Promise中then第二个参数与catch的区别

  • 如果在then的第一个函数里抛出了异常,后面的catch能捕获到,而then的第二个函数捕获不到
  • then的第二个参数和catch捕获错误信息的时候会就近原则,如果是promise内部报错,reject抛出错误后,then的第二个参数和catch方法都存在的情况下,只有then的第二个参数能捕获到,如果then的第二个参数不存在,则catch方法会捕获到。

2、使用Promise方式实现一个睡眠2秒的机制

init();
​
async function init(){
  var temp = await sleepFunc(2000);
  console.log('sleep 2s 后输出');
}
// Promise方式实现sleep方法
function sleepFunc(mitime) {
    return new Promise((resolve) =>{
        setTimeout(resovle, mitime)
    })
}
目录
相关文章
|
前端开发 JavaScript
promise自定义封装---初识结构搭建
promise自定义封装---初识结构搭建
89 0
|
前端开发 开发者
剖析Promise内部结构,一步一步实现一个完整的、能通过所有Test case的Promise类
本文写给有一定Promise使用经验的人,如果你还没有使用过Promise,这篇文章可能不适合你,建议先了解Promise的使用 Promise标准解读 1.
837 0
|
3月前
|
前端开发 JavaScript API
一文吃透 Promise 与 async/await,异步编程也能如此简单!建议收藏!
在前端开发中,异步编程至关重要。本文详解了同步与异步的区别,通过生活化例子帮助理解。深入讲解了 Promise 的概念、状态及链式调用,并引入 async/await 这一语法糖,使异步代码更清晰易读。还介绍了多个异步任务的组合处理方式,如 Promise.all 与 Promise.race。掌握这些内容,将大幅提升你的异步编程能力,写出更优雅、易维护的代码,助力开发与面试!
223 0
一文吃透 Promise 与 async/await,异步编程也能如此简单!建议收藏!
|
3月前
|
前端开发 JavaScript API
JavaScript异步编程:从Promise到async/await
JavaScript异步编程:从Promise到async/await
443 204
|
前端开发 JavaScript 开发者
Async 和 Await 是基于 Promise 实现
【10月更文挑战第30天】Async和Await是基于Promise实现的语法糖,它们通过简洁的语法形式,借助Promise的异步处理机制,为JavaScript开发者提供了一种更优雅、更易于理解和维护的异步编程方式。
250 1
|
9月前
|
前端开发
使用 async/await 结合 try/catch 处理 Promise.reject()抛出的错误时,有什么需要注意的地方?
使用 async/await 结合 try/catch 处理 Promise.reject()抛出的错误时,有什么需要注意的地方?
385 57
|
12月前
|
前端开发
如何使用async/await解决Promise的缺点?
总的来说,`async/await` 是对 Promise 的一种很好的补充和扩展,它为我们提供了更高效、更易读、更易维护的异步编程方式。通过合理地运用 `async/await`,我们可以更好地解决 Promise 的一些缺点,提升异步代码的质量和开发效率。
253 64
|
12月前
|
前端开发 JavaScript
async/await和Promise在性能上有什么区别?
性能优化是一个综合性的工作,除了考虑异步模式的选择外,还需要关注代码的优化、资源的合理利用等方面。
332 63
|
JSON 前端开发 JavaScript
浅谈JavaScript中的Promise、Async和Await
【10月更文挑战第30天】Promise、Async和Await是JavaScript中强大的异步编程工具,它们各自具有独特的优势和适用场景,开发者可以根据具体的项目需求和代码风格选择合适的方式来处理异步操作,从而编写出更加高效、可读和易于维护的JavaScript代码。
282 1