Lectura del código fuente: promesa
Lectura del código fuente: promesa
Introducción
En JavaScript, las funciones de devolución de llamada son una forma común de manejar operaciones asincrónicas. Sin embargo, el uso de funciones de devolución de llamada puede generar código que esté demasiado anidado para comprenderlo y mantenerlo. Promiseify
Para resolver este problema, puede convertir funciones asincrónicas basadas en devolución de llamadas en Promise
funciones devueltas, lo que facilita a los desarrolladores manejar operaciones asincrónicas y Promise
escribir código mediante llamadas en cadena, utilizando un código más claro y conciso para manejar operaciones asincrónicas.
Promiseify
El uso es muy simple, simplemente llame a su función y pase la función asincrónica que necesita convertirse como parámetro. Promiseify
Devolverá una nueva función, esta nueva función devuelve un Promise
objeto. Podemos realizar operaciones asincrónicas originales llamando a esta función devuelta y Promise
manejar resultados y errores mediante llamadas encadenadas.
promiseify
El uso básico es el siguiente:
- Importe
promiseify
el módulo (CommonJS como ejemplo):
const promiseify = require('promiseify');
- Pase la función que debe convertirse en
promiseify
función y obtenga laPromise
versión devuelta de la función:
const promiseFunc = promiseify(callbackFunc);
- Utilice la función devuelta
promiseFunc
para operaciones asincrónicas:
promiseFunc(args)
.then((result) => {
// 处理成功的结果
})
.catch((error) => {
// 处理错误
});
promiseify
El principio de funcionamiento consiste en envolver la función de devolución de llamada original en una nueva Promise
y determinar Promise
el estado en función del resultado de la ejecución de la función de devolución de llamada. Si la función de devolución de llamada se ejecuta correctamente, Promise
se como un estado de éxito y se pasará el valor del resultado; si la función de devolución de llamada falla, Promise
se rechazará y se pasará un objeto de error.
Interpretación del código fuente
'use strict';
Primero, el código utiliza el modo estricto ( 'use strict'
) para garantizar el rigor y la seguridad del código.
A continuación, se define una función promiseify
que acepta dos parámetros: method
y ctx
(opcional). method
El parámetro es la función que necesita convertirse y ctx
el parámetro es el contexto () que sirve como función this
.
/**
* promiseify
* @param {function} method function
* @param {object} ctx optional ctx for method
*/
function promiseify(method, ctx) {
// check first
if (typeof method !== 'function') {
throw new TypeError(String(method) + ' is not a function');
}
return function() {
// runtime args
var args = [].slice.call(arguments);
// runtime this
ctx = ctx || this;
return new Promise(function(resolve, reject) {
args.push(function(err) {
if (err) {
return reject(err);
}
var arg = [].slice.call(arguments);
if (arg.length === 2) {
resolve.call(this, arg[1]);
} else {
resolve.call(this, arg.slice(1));
}
});
try {
method.apply(ctx, args);
} catch (err) {
reject(err);
}
});
};
}
- El código primero realiza una verificación de parámetros para garantizar que el parámetro del método sea una función. Si no es una función, se genera un error de tipo.
- Luego, se devuelve una nueva función, que se convierte en la
Promise
versión devuelta de la función. - Dentro de la nueva función, primero obtenga los parámetros de tiempo de ejecución (
arguments
) y conviértalos en una matriz. this
A continuación, establezca el contexto de ejecución de la función según el parámetro de contexto pasado o el contexto predeterminado ( ).- Luego, cree uno nuevo
Promise
yPromise
pase una nueva función de devolución de llamada como parámetro en el constructor. Esta función de devolución de llamada acepta dos parámetros:resolve
yreject
. - En la función de devolución de llamada, primero verifique si hay un parámetro de error (
err
), si hay un error,reject
el método seráPromise
rechazado y se pasará el objeto de error. - Si no hay errores, utilice
[].slice.call(arguments)
Convertir los parámetros de la función de devolución de llamada en una matriz (arg
). resolve
A continuación, los parámetros pasados al llamar se determinan en función de la longitud de los parámetros . Si la longitud del parámetro es2
, significa que hay un parámetro de error y un parámetro de resultado. En este momento,resolve
se llama al método yarg[1]
se pasa el parámetro de resultado ( ); de lo contrario,resolve
se llama al método y se pasa la matriz de parámetros de resultado (arg.slice(1)
). aprobado.- Finalmente,
try-catch
la función asíncrona original (method.apply(ctx, args)
) se ejecuta en el bloque y, si ocurre un error, elreject
método consumidorPromise
lo rechazará y pasará el objeto de error.
/**
* promiseify all
* @param {object} o the target object
* @return {object} same to target object
*
* @example
* var fs = promiseify.all(require('fs'));
* fs.readFileAsync('file.txt', 'utf8')
* .then(function(s){ console.log(s); });
*
* var Connection = require('mysql/lib/Connection');
* promiseify.all(Connection.prototype);
* // conn.connectAsync / conn.queryAsync / conn.endAsync available now
*/
promiseify.all = function(o) {
Object.keys(o)
.filter(function(m) {
return typeof o[m] === 'function';
})
.forEach(function(m) {
o[m + 'Async'] = promiseify(o[m]);
});
return o;
};
Esta parte es una promiseify.all
función que toma un objeto como parámetro y recorre en iteración todas las propiedades de ese objeto. Para atributos cuyo valor es una función, conviértalo a Promise
una versión de la función y agregue la nueva función al objeto con el nombre de la función original más Async
un sufijo.
Object.defineProperty(promiseify, "__esModule", {
value: true });
promiseify.default = promiseify;
module.exports = promiseify;
Este código se utiliza principalmente para exportar promiseify
la función como módulo. Primero, use Object.defineProperty
el método para promiseify
agregar una "__esModule"
propiedad denominada al objeto con un valor de true
. Esto es para indicar que el módulo es un módulo ES. A continuación, establezca promiseify.default
la propiedad en promiseify
la función misma. De esta manera, cuando utilice import
la importación de sintaxis, puede obtener promiseify
la función directamente. Finalmente, use module.exports
exportar promiseify
la función como módulo. require
De esta forma, se puede obtener la función al utilizar la sintaxis import promiseify
.
expandir
En JavaScript, un objeto similar a una matriz se refiere a un objeto que tiene las características de una matriz, pero no es una verdadera matriz. Tienen una propiedad de longitud similar a una matriz y la capacidad de acceder a elementos por índice. Sin embargo, los objetos tipo matriz no tienen los métodos y propiedades prototipo de las matrices.
Los objetos comunes similares a matrices incluyen:
arguments
Objeto: un objeto creado automáticamente dentro de una función para almacenar los parámetros pasados a la función.- Lista de elementos DOM (NodeList): una colección de objetos devueltos al consultar elementos DOM, como
querySelectorAll
los resultados obtenidos a través de métodos. - Cadena: se puede acceder a los caracteres de una cadena mediante índice.
- Objetos similares a matrices: algunos objetos pueden diseñarse para parecerse a matrices, por ejemplo implementando una interfaz iteradora similar a una matriz.
Hay varias formas de convertir un objeto similar a una matriz en una matriz real:
- Uso
Array.from()
:Array.from()
El método puede convertir un objeto similar a una matriz o un objeto iterable en una nueva matriz. Por ejemplo:var array = Array.from(arrayLike);
- Utilice el operador de extensión (Operador de extensión): el operador de extensión (...) puede extender un objeto similar a una matriz en una nueva matriz. Por ejemplo:
var array = [...arrayLike];
- Uso : Puede convertir un objeto similar a una matriz en una matriz
Array.prototype.slice.call()
llamando al método y pasando un objeto similar a una matriz como contexto.Array.prototype.slice
Por ejemplo:var array = Array.prototype.slice.call(arrayLike);
- Uso
Array.prototype.concat()
: Puede convertir un objeto similar a una matriz en una matriz llamandoArray.prototype.concat
al método y pasando un objeto similar a una matriz como parámetro. Por ejemplo:var array = Array.prototype.concat.call([], arrayLike);
Cabe señalar que todos los métodos anteriores crean una nueva matriz en lugar de modificar directamente el objeto original similar a una matriz.