Promisification
On this page
JavaScript Promisification
Promisification is a long term for a straightforward transformation. It represents a conversion of the function, which accepts a callback into a function returning a promise. (承诺是一个直接转型的长期目标。它表示函数的转换,该函数接受回调为返回Promise的函数。)
Often, transformations like that are needed in real-life because multiple libraries and functions are based on callbacks. But, promises are much more convenient. (通常,现实生活中需要这样的转换,因为多个库和函数都是基于回调的。但是,承诺要方便得多。)
Let’s consider a load_Script(src, callback):
function load_Script(src, callback) {
let scriptJS = document.createElement('script');
scriptJS.src = src;
scriptJS.onload = () => callback(null, scriptJS);
scriptJS.onerror = () => callback(new Error(`Script load error for ${src}`));
document.head.append(scriptJS);
}
// usage:
// load_Script('path/script.js', (err, scriptJS) => {...})
Now, we are going to promisify it. The new load_Script_Promise(src) will get the same result accepting merely src. It returns a promise, like this:
let load_Script_Promise = function (src) {
return new Promise((resolve, reject) => {
load_Script(src, (err, script) => {
if (err) reject(err)
(if (err) reject (err))
else resolve(script);
});
})
}
// usage:
// load_Script_Promise('path/script.js').then(...)
So, it can be stated that ow load_Script_Promise suits well in a promise-based code. It delegates the overall work to the original load_Script and provides its callback, which translates to promise resolve/reject. (因此,可以说ow load_Script_Promise非常适合基于promise的代码。它将整个工作委托给原始LOAD_SCRIPT ,并提供其回调,转换为promise resolve/reject。)
Now, it’s necessary to use a helper. It can be called promisify(fn). It includes a to-promisify function f, returning a wrapper function. (现在,有必要使用帮助者。它可以被称为promisify (fn)。它包括一个to-promisify函数f ,返回一个包装函数。)
That wrapper does the same as the code, described above. It returns a promise and passes the call to the original fn. (该包装器的操作与上述代码相同。它返回一个promise并将调用传递给原始fn。)
The result is tracked in a custom callback, like here:
function promisify(fn) {
return function (...args) { // return wrapper function
return new Promise((resolve, reject) => {
function callback(err, result) { // our custom callback for fn
if (err) {
reject(err);
} else {
resolve(result);
}
}
args.push(callback); // append custom callback at the end of the fn arguments
fn.call(this, ...args); // call the original function
});
};
};
// usage:
let load_Script_Promise = promisify(load_Script);
load_Script_Promise(...).then(...);
In the example above, the function waits for a callback along with two arguments such as result and err. So, when the callback is in the correct format, the promisify operates more efficiently. (在上面的示例中,函数等待回调以及两个参数,如result和err。因此,当回调采用正确的格式时, Promisify的运行效率更高。)
Now, let’s discover a more complicated version of the promisify. After calling promisify(fn, true), the result of the promise will be an array of callback results, like this:
// promisify(fn, true) get an array of results
function promisify(fn, manyArgs = false) {
return function (...args) {
return new Promise((resolve, reject) => {
function callback(err, ...results) { // our custom callback for fn
if (err) {
reject(err);
} else {
resolve(manyArgs ? results : results[0]); // resolve with all callback results if manyArgs is specified
}
}
args.push(callback);
fn.call(this, ...args);
});
};
};
// usage:
fn = promisify(fn, true);
fn(...).then(arrayOfResults => ..., err => ...)
Also, there exist modules that have more flexible functions for promisification. (此外,还有一些模块具有更灵活的承诺功能。)
A built-in function, called util.promisify is used in Node.js. (Node.js中使用了一个名为util.promisify的内置函数。)
Summary
Summary (概要)
Promisification is a useful and widespread approach that makes a developer’s life more productive. It is especially great while using it with async/await. However, the complete replacement for callbacks is not recommended. (Promisification是一种有用且广泛的方法,可以使开发人员的生活更有效率。特别适合与async/await配合使用。但是,不建议完全替换回拨。)
It is important to note that a promise can have a single result. On the contrary, a callback can be called multiple times. (重要的是要注意,一个promise可以有一个单一的结果。相反,可以多次调用回调。)
So, promisification is used for the functions, calling the callback once. Upcoming calls are always ignored. (因此, Promisification用于函数,调用一次回调。将至呼叫始终被忽略。)