Comprensión de promesas y promesas manuscritas

introducir

Antes de comprender la promesa, primero debe comprender la parte básica, que se divide en el principio de la computadora, el principio del navegador y el principio de ejecución de JS.

principios de la computadora

proceso

Definición: Un proceso es la unidad más pequeña de asignación de recursos de CPU: un recurso independiente

hilo

Definición: Thread es la unidad más pequeña de programación de CPU: recurso compartido

Preguntas relacionadas

  1. Chrome abre una nueva ventana, ¿la página de pestañas es un proceso o un hilo? Respuesta: Proceso
  2. ¿Cómo se comunican los procesos (cómo se comunican las ventanas)? Respuesta: almacenamiento (localStorage, sessionStorage, cookie)
  3. ¿Diferencia entre varios almacenamientos?
  4. Principio del navegador (principalmente gestión de nivel medio y alto) El navegador tiene varios subprocesos en un proceso

Principio del navegador

motor de renderizado GUI

  1. Analizar html, css, construir dom tree => diseño => dibujar
  2. Es mutuamente excluyente con el motor js.Cuando se ejecuta el subproceso del motor JS, la GUI estará pendiente y continuará ejecutándose cuando la cola de tareas esté inactiva.

Hilo del motor JS

  1. Procesar JS, analizar y ejecutar scripts
  2. Asignar, procesar y ejecutar eventos para ser ejecutados, cola de eventos
  3. bloqueando la representación de GUI

El temporizador activa el motor.

  1. establecer tiempo de espera, establecer intervalo
  2. Recibir la tarea del temporizador asignada por el motor js y contarla
  3. Una vez que se completa el procesamiento, se entrega al subproceso de activación del evento para activar

Subproceso de solicitud HTTP asíncrono

  1. Ejecute el procesamiento de clase de solicitud de forma asíncrona, promesa/ajax, etc.
  2. Reciba el motor JS para enviar una solicitud HTTP asíncrona
  3. Escuche la devolución de llamada y déselo al hilo de activación del evento para activar

motor de activación de eventos

  1. Fuente de recepción: temporizador, asíncrono, acción del usuario
  2. Conecte los eventos de devolución de llamada al final de la cola de tareas y devuélvalos al motor

Principio de ejecución JS

Asignar memoria

pila de ejecución

Pregunta de la entrevista 1: orden de ejecución de la pila js, desbordamiento de la pila (explosión de la pila) =>
optimización Pregunta de la entrevista 2: operación de matriz problema de valor de retorno división de empalme... promesa.todo promesa.carrera

Cola de tareas
Macro tarea: macro: script, setTimeout, setInterval, I/O
micro tarea: nueva promesa{}.then()

Hay microtareas, y las macrotareas siempre preceden a las microtareas

1. Comprensión profunda de las promesas

especificación de la promesa

promise是一个有then方法的对象或者函数,promise有三种状态

状态
  1. pending: 初始状态 - 可改变
  2. fulfilled:最终状态 - 不可改变
  3. rejected:最终状态 - 不可改变
状态变化
  1. pending -> reslove(value) -> fulfilled
  2. pending -> reject(reason) -> rejected
then方法
  1. 参数:onFulfilledonRejected(两个参数必须是函数,如果不是函数,应该被忽略)
  2. onFulfilledonReject是微任务 (js是单线程,分为了同步任务和异步任务,而异步任务中也有优先级,微任务即表示优先级高的)
  3. then方法可以调用多次,用数组来存放多个onFulfilled的回调和onRejected的回调
  4. then方法的返回值是一个新的promise 将onFulfilled或onrejected的返回结果为x,通过resolvePromise来解析promise this.resolvePromise(promise2, x, resolve, reject);

2.一步步实现一个promise

  1. class对象并定义三种状态
  2. constructor中设置初始状态以及定义value和reason
  3. 实现resolve和reject方法,在状态为pending时改变状态
  4. constructor中传一个入参fn,fn接收resolve和reject,若报错则通过reject抛出去
  5. 实现then方法,接收两个参数:then(onFulfilled, onRejected) {}
  6. 检查处理then参数,判断onFulfilled和onRejected是否为函数,若不是函数,则返回value或reason
  7. 定义返回值(promise2)并根据当前promise的状态调用不同的函数
  8. 设置一个状态的监听机制, 当状态变成fulfilled或者rejected后, 再去执行callback
  9. 新建两个数组, 来分别存储成功和失败的回调, 调用then的时候, 如果还是pending就存入数组
  10. 实现getter和setter函数,在给status赋值后, 下面再加一行forEach
  11. 当 onFulfilled 或者 onRejected 抛出异常 e ,则 promise2 拒绝执行,并返回拒因 e。(这样的话, 我们就需要手动catch代码,遇到报错就reject)
  12. 当onFulfilled 或者 onRejected 返回一个值 x ,则运行resolvePromise方法。将realOnFulfilled(this.value)赋值给x,this.resolvePromise(promise2, x, resolve, reject);
  13. 实现resolvePromise方法
  14. onFulfilled 和 onRejected 是微任务,使用queueMicrotask包裹执行函数
  15. 实现catch方法

3.Iterator,Generator和async的理解

Interator迭代器
  1. 是一种的特殊的对象,每一个迭代器对象都有一个next方法,
  2. 每次调用都会返回一个劫夺对象,结果对象中包含两个值:
    value: 当前属性的值;
    done: 判断是否遍历结束
Generator生成器
  1. 生成器时一种返回迭代器的函数,函数中会用到新的关键字yield,使用function*来创建
function* generator() {
    const list = [1, 2, 3];
    for (let i of list) {
        yield i;
    }
}
let g = generator();
console.log(g.next()); // {value: 1, done: false}
console.log(g.next()); // {value: 2, done: false}
console.log(g.next()); // {value: 3, done: false}
console.log(g.next()); // {value: undefined, done: true}
复制代码
  1. 注意
  • 每当执行完一条yield语句后函数就会自动停止执行, 直到再次调用next();
  • yield关键字只可在生成器内部使用,在其他地方使用会导致程序抛出错误;
  • 可以通过函数表达式来创建生成器, 但是不能使用箭头函数
    let generator = function *(){}

4.面试中可能会遇到的问题

  1. 为什么promise resolve了一个value, 最后输出的value值确是undefined
const test = new MPromise((resolve, reject) => {
    setTimeout(() => {
        resolve(111);
    }, 1000);
}).then((value) => {
    console.log('then');
});

setTimeout(() => {
    console.log(test);
}, 3000)
复制代码

答:因为在.then中没有return则相当于return undefined,所以value是undefined

  1. 为什么在catch的回调里, 打印promise, 显示状态是pending
const test = new MPromise((resolve, reject) => {
    setTimeout(() => {
        reject(111);
    }, 1000);
}).catch((reason) => {
    console.log('报错' + reason);
    console.log(test)
});

setTimeout(() => {
    console.log(test);
}, 3000)
复制代码

答:catch函数会返回一个新的名为test的promise函数,在catch中还没有执行完成,所以是pending

Supongo que te gusta

Origin juejin.im/post/7080141138232868901
Recomendado
Clasificación