Después de leer este artículo, no puedes decir que no entiendes [Promise] en la entrevista inicial.


1. ¿Infierno de devolución de llamada?

Para entender Promise, primero debo entender qué es el infierno de devolución de llamada. (Si lo entiende, pase directamente a la siguiente sección)
Las funciones asincrónicas no pueden garantizar la ejecución secuencial
inserte la descripción de la imagen aquí

const fs = require('fs')
fs.readFile('./data/a.txt', 'utf-8', (err, data) => {
    
    
    if (err) {
    
    
        console.log('读取失败');
    }
    console.log(data);
})

fs.readFile('./data/b.txt', 'utf-8', (err, data) => {
    
    
    if (err) {
    
    
        console.log('读取失败');
    }
    console.log(data);
})

fs.readFile('./data/c.txt', 'utf-8', (err, data) => {
    
    
    if (err) {
    
    
        console.log('读取失败');
    }
    console.log(data);
})

inserte la descripción de la imagen aquí
Como se puede ver en el caso anterior, ejecuté el 回调地狱.jsarchivo js tres veces en total. Las dos primeras secuencias de ejecución fueron aaa bbb ccc, y la tercera vez se convirtió en aaa ccc bbb
. Por lo tanto, se puede demostrar que la función asíncrona de No se puede garantizar que Js se ejecute.


Pero a veces, necesitamos la secuencia de ejecución de estas funciones asincrónicas para estar seguros.
Podemos leer el archivo a, después de que la consola imprima el resultado de los datos del archivo a, luego lea el archivo b, y la consola imprima... hasta que Se imprime el archivo c. El contenido de los datos:

const fs = require('fs')
fs.readFile('./data/a.txt', 'utf-8', (err, data) => {
    
    
    if (err) {
    
    
        console.log('读取失败');
    }
    console.log(data);	
    //控制台打印完a文件内容后,读取b文件
    fs.readFile('./data/b.txt', 'utf-8', (err, data) => {
    
    
        if (err) {
    
    
            console.log('读取失败');
        }
        console.log(data);
        //控制台打印完b文件内容后,读取c文件
        fs.readFile('./data/c.txt', 'utf-8', (err, data) => {
    
    
            if (err) {
    
    
                console.log('读取失败');
            }
            console.log(data);
        })
    })
})

inserte la descripción de la imagen aquí
Después de anidar y volver a anidar, podemos obtener resultados de ejecución estables. Sin embargo, el orden de ejecución está determinado, pero dicho código está profundamente anidado, lo que no es conveniente para nuestros programadores mantenerlo más adelante. ¿Qué? Crees que esto está bien, si puedes entenderlo, ¿qué tal si miras esto?
inserte la descripción de la imagen aquí
¿No es repugnante... = =

二, Promesa

Entonces, si no queremos usar este método profundamente anidado, pero también queremos permitir que las funciones asincrónicas se ejecuten en orden, ¿hay alguna otra manera?
¡Por supuesto! ES6 nos proporciona una interfaz llamada Promise, que se usa especialmente para resolver situaciones como el infierno de devolución de llamada.

Como sugiere el nombre, Promisesignifica en chino “承诺”que todos deberíamos tener promesas a otros escenas de nuestras vidas pasadas, tales como: Prometes a tu novia: Cuando ella tenga XX, organizaré una boda romántica para nosotros.
Cuando le haces una promesa a tu novia de "celebrar una boda", ahora estás 目前的状态: trabajando horas extras y tratando de cumplir la promesa (pendiente), sin embargo 在未来, solo hay dos posibilidades (estados): 1. Exitoso (resuelto) 2. Fallo
Por lo que se concluye que el estado pendiente sólo puede transformarse en uno de resolver o rechazar
inserte la descripción de la imagen aquí


Entonces, ¿qué es exactamente una Promesa? ¿Cómo resuelve el infierno de devolución de llamada?

  • Las promesas son esencialmente un constructor
  • El objeto de la instancia de Promise se denomina 'instancia de Promise, que se puede utilizar para obtener el resultado del éxito o fracaso interno de Promise.

Es normal no entender, por favor vea el siguiente ejemplo:

const fs = require('fs')

new Promise(function(resolve,reject) {
    
    
	
	//读取文件
    fs.readFile('./data/a.txt','utf-8',(err,data) => {
    
    
        if(err) {
    
    
            //读取失败,调用reject函数
            reject(err)
        }
        //读取成功,调用resolve函数
        resolve(data)
    })
    
})

Como se puede ver en el código anterior, después de que se complete la nueva promesa, se pasará una función al constructor como parámetro, y dentro de esta función, está su código asíncrono, por lo que parece que Promise es como un contenedor que envuelve su código asíncrono. función _

const fs = require('fs')

let p1 = new Promise(function(resolve,reject) {
    
    
	//读取文件
    fs.readFile('./data/a.txt','utf-8',(err,data) => {
    
    
        if(err) {
    
    
            //读取失败,调用reject函数
            reject(err)
        }
        //读取成功,调用resolve函数
        resolve(data)
    })   
})

p1.then(function(data){
    
    
    console.log(data);	//aaa
})

Podemos ver que Promise instancia p1, y p1 llama a la función luego en su cuerpo, y la función de parámetro en esta función entonces es la función de resolución dentro de Promise.
inserte la descripción de la imagen aquí
Por lo tanto, el valor de los datos se obtiene externamente.

3. Promise resuelve el problema de las devoluciones de llamada

En el caso anterior, aprendimos el uso básico de Promise, luego usaremos Promise para resolver el infierno de devolución de llamada.

const fs = require('fs')
const p1 = new Promise(function(resolve,reject) {
    
    
    fs.readFile('./data/a.txt','utf-8',(err,data) => {
    
    
        if(err) {
    
    
            console.log('读取失败');
            reject(err)
        }
        resolve(data)
    })
})

const p2 = new Promise(function(resolve,reject) {
    
    
    fs.readFile('./data/b.txt','utf-8',(err,data) => {
    
    
        if(err) {
    
    
            reject(err)
        }
        resolve(data)
    })
})

const p3 = new Promise(function(resolve,reject) {
    
    
    fs.readFile('./data/c.txt','utf-8',(err,data) => {
    
    
        if(err) {
    
    
            reject(err)
        }
        resolve(data)
    })
})

p1.then(function(data) {
    
    
    console.log(data);
    return p2
}).then(function(data) {
    
    
    console.log(data);
    return p3
}).then(function(data) {
    
    
    console.log(data);
})

Aunque el código anterior es un poco largo, lo comprenderá lentamente después de leerlo.
Porque en la función p1.then, su parámetro de función interna devuelve la Promesa de p2, luego en la siguiente parte de .then, este parámetro de función es la función de resolución de la Promesa anterior , lo que suena muy complicado, cierto, podemos entenderlo mirando la figura a continuación:
inserte la descripción de la imagen aquí
porque obtuvimos los datos de manera ordenada.
Esto se llama encadenamiento de promesas y resuelve el infierno de devolución de llamada.

Supongo que te gusta

Origin blog.csdn.net/weixin_60297362/article/details/123206078
Recomendado
Clasificación