Prefacio
Un objeto de promesa puede entenderse como una operación a realizar (a menudo se usa para operaciones asincrónicas). Después de usar el objeto Promise, el código se puede organizar en una forma de llamada en cadena para hacer que el código sea más intuitivo. Además, debido a que la existencia de un método como prometía. Todo, puede ser fácil realizar múltiples operaciones al mismo tiempo.
El aumento de la promesa es porque en las llamadas de método asincrónico, las funciones de devolución de llamada a menudo ocurren una tras otra. Esta situación ha llevado a la aparición de problemas de la pirámide de devolución de llamada. El código no solo es difícil y no es hermoso de escribir, sino que también dificulta que las personas que lean el código entiendan cuándo el problema es complicado.
Como ejemplo:
db.save (data, function (data) {// hacer algo ... db.save (data1, function (data) {// hacer algo ... db.save (data2, function (data) {// hacer algo ... hecho (data3); // return data})});}); Supongamos que hay una operación de guardar la base de datos, y una solicitud requiere que los datos se guarden tres veces en tres tablas. Entonces nuestro código es similar al código anterior. ¿Qué debo hacer si hay un problema en el segundo db.save en este momento? Según esta consideración, necesitamos usar la lógica como try...catch en cada capa de devolución de llamada. Esta es la fuente de todo mal, y también es un punto en que el nodo fue ampliamente criticado al principio.
Otra desventaja es que suponiendo que no hay una dependencia delantera y hacia atrás entre nuestros tres salvamentos, aún debemos esperar a que se ejecute la función anterior antes de ejecutar el siguiente paso, y los tres salvamentos no pueden ser paralelos, y luego devolver el resultado requerido después de los tres salvamentos. (O requiere habilidades para implementarlo)
Desafortunadamente, cuando comencé a involucrarme en el nodo, escribí muchos infiernos como este.
Más tarde, debido a que todavía escribí más código frontal, entré en contacto con ES6 y encontré una herramienta poderosa para resolver el abismo de devolución de llamada.
De hecho, mucho antes de la promesa de ES6, Q, When.js, Bluebird y otras bibliotecas ya habían construido sus propias ruedas de promesa en función del estándar de promesa (consulte la promesa/A+).
(Leí un artículo y creo que tiene sentido. Dice que no debe extender los objetos nativos incorporados. Este enfoque no puede estar orientado al futuro. Así que aquí hay un consejo: tenga cuidado cuando use bibliotecas que extienden la promesa nativa).
Solo la promesa nativa se discute aquí.
ES6 Promesa
Estado de objeto de promesa
Antes de explicar la promesa en detalle, primero tomemos una teoría:
La especificación de promesa/A+ estipula que el objeto Promise es una máquina de estado finito.
Tiene tres estados:
1. pending (ejecución)
2. fulfilled (exitoso)
3. reject
Donde está pending el estado inicial, fulfilled y rejected son los estados finales (el estado final indica que el ciclo de vida de la promesa ha terminado).
La relación de transición estatal es:
pendiente-> cumplido, pendiente-> rechazado.
Varios eventos (como eventos de ejecución exitosos, eventos de ejecución fallidos, etc.) se activarán a medida que las transiciones estatales.
Forma de promesa
La promesa se ve así:
var promise = new promise (function func (resolve, rechazar) {// haz algo, tal vez async if (éxito) {return resolve (data);} else {return rechaze (data);}}); promet.then (function (data) {// haz algo ... eg console.log (data);}, function (err) {// acuerdo el res.})La promesa variable aquí es una instancia del objeto de promesa.
Cuando se crea el objeto Promise, se ejecutará la lógica en func .
Cuando se procesa la lógica y no hay errores, la devolución de llamada resolve pasará el valor a un lugar especial. ¿Dónde está este lugar especial? Eso es entonces en el siguiente código. Usamos la función de devolución de llamada en then para procesar el resultado después de resolve . Por ejemplo, en el código anterior, simplemente generamos el valor en la consola. Si hay un error, reject en la segunda función de devolución de llamada de then para procesar el error.
En línea con la teoría anterior de la máquina de estado finito, sabemos que al ejecutar el código de función de devolución de llamada en el constructor de promesas, el estado está pending , el estado se fulfilled después de resolve , y el estado es reject después de reject
Flujo de datos de promesa
Lo anterior es el primer flujo de datos de la promesa.
Lo divertido es que el método de promesa then puede devolver un objeto de promesa, para que podamos usar el siguiente then hacer el mismo procesamiento.
Las dos funciones de devolución de llamada en el primero then qué tipo de objeto de promesa regresa el then .
Suponiendo que la primera devolución de llamada del then no devuelve un objeto de promesa, entonces la persona que llama al segundo then siendo el objeto de promesa original, excepto que su valor de resolución se convierte en el valor de retorno de la primera función de devolución de llamada en el primero.
Suponiendo que la then función de devolución de llamada devuelve un objeto prometedor, el segundo then la persona que llama se convierte en este nuevo objeto de promesa, y el segundo then que el nuevo objeto de promesa resuelva o rechace y ejecute la devolución de llamada.
Aunque me he escabricado un poco, siento que todavía estoy muy claro al respecto. Jaja ~
Si se encuentra un error en cualquier lugar, el error se entrega a la segunda función de devolución de llamada then con la segunda función de devolución de llamada para manejarlo. Se puede entender que el error reject hacia atrás hasta que se procesa.
Además, el objeto Promise también tiene una catch de método, que acepta una función de devolución de llamada para manejar errores.
Ahora mismo:
promet.catch (function (err) {// trata el err.})Suponiendo que el manejo de errores es similar, este método puede manejar los errores centrales y uniformemente. Por lo tanto, otros métodos no requieren una segunda devolución de llamada ~
Controlar promesas concurrentes
Promise tiene un "método estático" - Promise.all (tenga en cuenta que no es prometedor.prototype). Este método acepta un elemento que es una variedad de objetos de promesa.
Este método también devuelve un objeto de promesa. Si se resolve todos los objetos de promesa en la matriz, los valores resolve se utilizarán como una matriz como el valor resolve del (objeto prometedor) del valor de retorno del then Promise.all . Si reject alguna promesa en la matriz, entonces el valor reject es el valor reject del valor de retorno de Promise.all Todo método.
Un punto muy opaco es:
El orden del valor resolve (como se mencionó anteriormente, una matriz) recibida por la primera función de devolución de llamada del método then es el mismo que el orden de la matriz de parámetros en Promise.all , en lugar de en orden cronológico.
También hay un método similar a Promise.all Promise.race , que también recibe una matriz, excepto que solo acepta el primer valor resolve .
Convertir otros objetos en objetos de promesa
El método Promise.resovle puede devolver un objeto Promise como parámetro.
Hay dos situaciones:
Suponiendo que no hay .then método del parámetro aprobado, entonces el objeto de promesa devuelto se convierte en resolve , y el valor resolve es el objeto en sí.
Suponiendo que el parámetro aprobado tiene un método then (llamado objeto thenable ), entonces el tipo de este objeto se cambia a prometer, y su método then se convierte en Promise.prototype.then .
¿Es la promesa una solución a asíncrono?
Finalmente, permítanme decir algo muy importante: la función de la promesa es resolver el problema de las pirámides de devolución de llamada, y en realidad no juega un papel importante en el control del proceso asincrónico. Para usar realmente la promesa de controlar el proceso asincrónico, también necesitamos usar la función generator ES6. (Por ejemplo, la implementación de la Biblioteca CO de TJ Master).
Sin embargo, ES7 tendrá una solución más impresionante: async/await , que es similar a la CO, pero tiene soporte nativo. Esperemos y veamos.
Resumir
Lo anterior se trata de la promesa nativa en JavaScript ES6. Espero que el contenido de este artículo sea útil para todos en el aprendizaje ES6. Si tiene alguna pregunta, deje un mensaje para comunicarse.