promesa. luego secuencia de llamadas en cadena


Quiero usar Promise para implementar asincrónicamente una interfaz de llamada recursiva para secuencias de acción de IA simples. Descubrí que cuando contacté por primera vez, no estaba muy claro, hice referencia a algunos métodos de escritura en Internet y lo cambié a mis propios problemas, así que primero cálmate y estudia la secuencia de llamadas.

Ejemplos

Primero mire un ejemplo, consulte [1]

 new Promise((resolve, reject) => {
  console.log("promise")
  resolve()
 })
    .then(() => {	// 执行.then的时候生成一个promise是给最后一个.then的
        console.log("then1")
        new Promise((resolve, reject) => {
            console.log("then1promise")
            resolve()
        })
  .then(() => {// 执行这个.then的时候,生成的promise是下面一个then的
   console.log("then1then1")
  })
  .then(() => {
   console.log("then1then2")
  })
    })
    .then(() => {
  // 这个
        console.log("then2")
    })

El resultado:

promise
then1
then1promise
then1then1
then2
then1then2

Pregunta: Principalmente duda que then2 esté entre then1then1 y then1then2

Desmitificar

Teoría

Para facilitar el análisis, enumere algunos de sus propios conocimientos, y es conveniente al explicar el problema más adelante. Especialmente Teoría 4 y Teoría 5

Teoría 1: la promesa es un objeto

La promesa es un objeto, él contiene

  • Propio cuerpo de la función: un parámetro pasado en un nuevo momento es una función
  • Estado: cumplido, pendiente, rechazado
  • Cola de función asíncrona: luego el cuerpo de devolución de llamada colocado aquí en estado pendiente

Teoría 2: resolver / rechazar se utiliza para cambiar el objeto Promesa

  • resolver: Pendiente cambiado a cumplido
  • rechazar: pendiente cambiado a rechazado.
    Además, cuando se ejecuta ** resolver, verificará la propia cola de Promise. Si no está vacía, rellenará el cuerpo de la función de devolución de llamada en la cola nextTick. ** Código de referencia [4]
handlers.resolve = function (self, value) {
  var result = tryCatch(getThen, value);
  if (result.status === 'error') {
    return handlers.reject(self, result.value);
  }
  var thenable = result.value;

  if (thenable) {
    safelyResolveThenable(self, thenable);
  } else {
    self.state = FULFILLED;
    self.outcome = value;
    var i = -1;
    var len = self.queue.length;
    while (++i < len) {
      self.queue[i].callFulfilled(value);
    }
  }
  return self;
};

Teoría 3: el método t'hen / catch de Promise devuelve un objeto Promise después de la ejecución

Consulte [2], el objeto Promesa devuelto admite llamadas encadenadas

Teoría 4: ¿Cuándo se resuelve el objeto Promesa devuelto por la función then para ver el valor devuelto?

Consulte la sección [2] Valor de retorno

(1)返回了一个值,那么 then 返回的 Promise 将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。
(2)没有返回任何值,那么 then 返回的 Promise 将会成为接受状态,并且该接受状态的回调函数的参数值为 undefined。
(3)抛出一个错误,那么 then 返回的 Promise 将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。
(4)返回一个已经是接受状态的 Promise,那么 then 返回的 Promise 也会成为接受状态,并且将那个 Promise 的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。
(5)返回一个已经是拒绝状态的 Promise,那么 then 返回的 Promise 也会成为拒绝状态,并且将那个 Promise 的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。
(6)返回一个未定状态(pending)的 Promise,那么 then 返回 Promise 的状态也是未定的,并且它的终态与那个 Promise 的终态相同;同时,它变为终态时调用的回调函数参数与那个 Promise 变为终态时的回调函数的参数是相同的。

Teoría 5: la secuencia de ejecución es: ejecución síncrona> cola nextTick> cola setTimeout> cola privada del objeto Promise

Consulte [3], el artículo está bien escrito. En términos generales, entiendo el principio de Promesa y luego. Debido a que las capturas de pantalla en el artículo no son muy claras, todavía voy a github y miro el código fuente para ver el punto de comodidad, consulte [4]

Promise.prototype.then = function (onFulfilled, onRejected) {
  if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
    typeof onRejected !== 'function' && this.state === REJECTED) {
    return this;
  }
  var promise = new this.constructor(INTERNAL);
  if (this.state !== PENDING) {
    var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
    unwrap(promise, resolver, this.outcome);
  } else {
    this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
  }

  return promise;
};

Breve descripción:

    1. Cuando se ejecuta la función then, si se cumple el estado Promesa, se ejecuta la lógica de desenvolver y el cuerpo de la función se coloca en una cola global a través de nextTick
    1. Cuando se ejecuta la función then, si la Promesa está en el estado Pendiente, se ejecuta this.queue.push . Cuando vea esto, sabrá que se coloca en una cola del propio objeto Promesa

Análisis de tiempo

Con el entendimiento anterior, analicemos los resultados de impresión que no entendí al principio. Algunos pasos son simples y claros, puede que haya pasado. Por supuesto, porque entré en contacto con esto por primera vez, por lo que los pasos serán más engorrosos ~

  • 1. Cuando se ejecuta Promise, el cuerpo de la función se ejecuta sincrónicamente y se resuelve directamente, por lo que el objeto Promise está en el estado cumplido. [Teoría 1, Teoría 2]
  • 2. Cuando la función then1 se ejecuta sincrónicamente, entonces es una función, pero sus parámetros (cuerpo de la función dentro) no se ejecutan. Este cuerpo de función se coloca en la cola NextTick [Teoría 5]. Cuando se ejecuta then1, un objeto Promesa anónimo se devuelve sincrónicamente [Teoría 3]. Y el estado de este objeto Promise es Pendiente, porque el cuerpo de la función then1 relacionado con este objeto no se ha ejecutado [Teoría 4]
  • 3. Ejecute sincrónicamente then2. Como se indicó anteriormente, se basa en el estado anónimo del objeto Promesa devuelto por entonces1. Como está pendiente, el cuerpo de then2 se coloca en su propia cola de objetos de Promesa anónimos devueltos por ese1
  • 4. El siguiente ciclo ejecuta la cola nextTick, que es el cuerpo de la función de1
  • 5. Primero ejecute un nuevo cuerpo de función de objeto Promesa, imprima el 'entonces1 promesa'. Y el estado de este objeto Promesa se resuelve como cumplido
  • 6. Ejecute simultáneamente la función then.then1.then y coloque sus parámetros (cuerpo de la función de devolución de llamada) en la cola nextTick. Y el objeto Promesa anónimo devuelto está en estado pendiente
  • 7. Ejecute sincrónicamente la función then1then2.then, porque el cuerpo de la función callback then1then1 aún no se ha ejecutado, devuelve un objeto Promesa anónimo en el estado pendiente. Por lo tanto, el cuerpo de la función callback de la función then1then2 se coloca en la cola del objeto Promesa anónimo
  • 8. Finalmente, el cuerpo de la función then1 no devolvió nada, así que de acuerdo con la [Teoría 4], el estado de esta Promesa se cumplió, es decir, el estado del primer objeto Promesa devuelto por la función then1 cambió. En este momento, el estado de la función de resolución se ejecuta realmente. Esta función verá si hay una función de devolución de llamada en la propia cola del objeto Promise y luego la colocará en la cola timeTick [teoría 3]. Por lo tanto, el cuerpo de la función de devolución de llamada de .then2 se mueve de la cola del objeto Promise a la cola nextTick. Tenga en cuenta que los cuerpos de función de then1, then1 y then2 están en la cola de verificación en este momento, pero no se ejecutan. Además, js es de un solo subproceso, y el cuerpo de la función de devolución de llamada en la cola de marcación se ejecutará en secuencia, por lo que luego se ejecutarán en orden.
  • 9. En el siguiente ciclo, ejecute los cuerpos de las funciones de devolución de llamada then1, then1 y then2 respectivamente, para que imprima 'then1then1' primero, luego 'then2'
  • 10. Cuando se ejecuta el cuerpo de la función de devolución de llamada then1then1, su objeto Promise también se cambiará a cumplido y colocará el cuerpo de la función de devolución de llamada then1then2 en la cola de marca
  • 11. El siguiente ciclo. Finalmente ejecute el cuerpo de la función then1then2 e imprima 'then1then2'. Final perfecto

Practica

¿Qué pasa si la nueva promesa en el ejemplo se cambia a una devolución?

.then(() => {	// 执行.then的时候生成一个promise是给最后一个.then的
        console.log("then1")
        new Promise((resolve, reject) => {
            console.log("then1promise")
            resolve()
        })

// ===》改成
.then(() => {	// 执行.then的时候生成一个promise是给最后一个.then的
        console.log("then1")
        // 就是这里的加了一个return
        return new Promise((resolve, reject) => {
            console.log("then1promise")
            resolve()
        })

De acuerdo con la [Teoría 4], el cuerpo de la función .then1 tiene un valor de retorno, que es un objeto Promesa, y es un objeto Promesa anónimo devuelto después de la ejecución de then1then2. Entonces, solo después de que se resuelva el objeto Promise, se ejecutará la lógica del cuerpo de la función de devolución de llamada then2, por lo que se imprimirá 'then2' al final. Entonces el resultado final es:

promise
then1
then1promise
then1then1
then1then2
then2

Referencia

[1] Orden de ejecución de promesa anidada
[2] Promesa . Luego
[3] Implementación de la promesa
[4] mentira
[5] Promesa
[6] Promesa encadenada llamada secuencia de orden de pensamiento

Publicó 41 artículos originales · elogió 7 · 20,000+ visitas

Supongo que te gusta

Origin blog.csdn.net/pkxpp/article/details/104886823
Recomendado
Clasificación