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



请遵守《互联网环境法规》文明发言,欢迎讨论问题
扫码反馈

扫一扫,反馈当前页面

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