Promisification

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用于函数,调用一次回调。将至呼叫始终被忽略。)

扫码反馈

扫一扫,反馈当前页面

咨询反馈
扫码关注
返回顶部