This is the 7th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.


One, foreword

Last week, we implemented two static apis for Promise: Promise.allSettled and Promise.any.

  • Test the use of native Promise.allSettled;
  • Promise. AllSettled function and feature analysis;
  • Promise. AllSettled source code implementation, execution analysis, functional testing;
  • Test the use of native promise.any;
  • Promise.any function and feature analysis;
  • Promise. Any source code implementation, execution analysis, functional testing;

This article implements a promisify utility function;


Promisify introduction

1. What is promisify

Promisify function: as literally “promisify”

For converting an operation or API in the form of an asynchronous callback to a Promise form;

2. Promisify application scenario

Currently, nodeJS and applets are used

The apis provided by these frameworks are mostly asynchronous callback, which is easy to cause the “callback hell” problem in coding.

Example: Nodejs asynchronously reads a file

const fs = require('fs') // File manipulation
fs.readFile('test'.'utf8'.function(err, data){
  if(err) reject(err) // Error first
  fs.readFile(data, 'utf8'.function(err, data){
   if(err) reject(err)
   console.log(data);
   // ...})})Copy the code

There is also a promisify function in the Util toolkit provided by NodeJS:

const fs = require('fs')
const util = require('util')
// Make the asynchronous API readFile -> promise in callback form
let readFile = util.promisify(fs.readFile);
readFile('test'.'utf8').then((data) = >{
  return readFile(data, 'utf8');
}).then((data) = >{
  console.log(data);
}).catch(err= >{/ /... })
Copy the code

Also provides batch promisify operations:

let fs = require('fs');
promisifyAll(fs); // Export objects to fs library as a whole promisify;

fs.readFileAsync('test'.'utf8').then(data= >{
  console.log(data);
});
Copy the code

Note: After a promisifyAll operation is performed on an object exported from the library as a whole, the new method name is as follows: old method name +”Async”;

Avoiding multiple layers of nesting caused by asynchronous callbacks improves code readability;

So let’s implement a promisify together;


Promisify implementation

  • Implement promisification of a single function:
function promisify(fn) {
  return function (. args) {
    return new Promise((resolve, reject) = >{ fn(... args,(err, data) = > {
        if(err) reject(err); resolve(data); }}})})Copy the code

Fn then wraps the callback into a promise;

  • Batch promisification:
function promisifyAll(obj) {
  // Convert objects to arrays, iterate over fn's in the array, and perform promisify operations in turn
  Object.keys(obj).forEach(key= > {
    if (typeof obj[key] === 'function') {
      obj[key + 'Async'] = promisify(obj[key])
    }
  })
}
Copy the code

Note: Many frameworks and libraries have API support for promise, so you can refer to the documentation when using promise. If not, you can use the promisify function above to convert promise. For example, bluebird.js can be used


Four, the end

Implementing a promisify tool function involves the following points:

  • Promisify Introduction and Testing;
  • Promisify implementation: promisify, promisifyAll;

The next article introduces generators; –