美文网首页
[Javascript] promisify函数

[Javascript] promisify函数

作者: 平仄_pingze | 来源:发表于2018-02-08 14:23 被阅读846次

前言

随着Promise的广泛使用,我们习惯于将一般的使用回调的函数,转为返回Promise对象的函数,以供书写同步代码。
bluebird库提供了快速转换普通函数的方法:bluebird.Promise.promisify(),但是其内部设计用来支持回调函数第一个参数为err对象的标准范式,不适用于自定义的特别函数。
这里提供了一个优化的promisify(),可以通过额外参数支持特别类型的函数。

声明

promisify(fn, callbackErr, reverse)

  • fn <function> 被包装的函数
  • callbackErr <boolean> (default:true) fn的回调函数参数,其第一个参数是否为err对象
  • reverse <boolean> (default:false) fn的回调函数参数,是否是第一个参数(如setTimeout)

源码

function promisify(fn, callbackErr=true, reverse=false) {
  if ({}.toString.call(fn) !== '[object Function]') throw new TypeError('Only normal function can be promisified');
  return function (...args) {
    return new Promise((resolve, reject) => {
      const callback = function (...args) {
        if (!callbackErr) {
          if (args.length === 1) return resolve(args[0]);
          return resolve(args);
        }
        const err = args.shift();
        const rest = args;
        if ({}.toString.call(err) === '[object Error]') return reject(err);
        if (rest.length === 1) return resolve(rest[0]);
        return resolve(rest);
      };
      try {
        if (reverse === true) fn.apply(null, [callback, ...args]);
        else fn.apply(null, [...args, callback]);
      } catch (err) {
        reject(err);
      }
    });
  }
}

使用

// 系统函数
const lstat = promisify(require('fs').lstat);
lstat('./index.js')
  .then((stats) => {
    console.log(stats)
  })
  .catch(err => console.warn('Catch error:', err));

// 自定义函数 
function foo(a, b, cb) {
  if(cb) cb(a+b);
}
const fooP = promisify(foo, false);
fooP(1, 2)
  .then(res => console.log('res', res))
  .catch(err => console.warn('Catch error:', err));

// setTimeout
const wait = promisify(setTimeout, true, true);
wait(1000).then(() => console.log('1秒后打印'));

// 方法,需要bind对象
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database(':memory:');
db.allP = promisify(db.all.bind(db)); 
db.allP('SELECT * FROM test').then(rows => console.log(rows));

相关文章

  • [Javascript] promisify函数

    前言 随着Promise的广泛使用,我们习惯于将一般的使用回调的函数,转为返回Promise对象的函数,以供书写同...

  • Promisify函数

    异步函数promise化 题目: 借助以下几个函数,分别使用ES5和ES6中的Promise(可借助所提供的pro...

  • node核心模块

    Node的核心模块 util.promisify 将普通的回调函数,转换成promise函数 但必须是规范的Nod...

  • Javascript 函数缺省值

    Javascript 函数 Javascript 函数缺省值写法

  • JavaScript函数式编程

    读完《JavaScript函数式编程》《JavaScript函数式编程指南》这两本书,对JavaScript函数式...

  • JavaScript函数式编程

    读完《JavaScript函数式编程》《JavaScript函数式编程指南》这两本书,对JavaScript函数式...

  • JavaScript函数

    layout: posttitle: JavaScript函数tags: [JavaScript, 函数]auth...

  • JavaScript encodeURI() 函数

    JavaScript encodeURI() 函数 JavaScript 全局函数](https://www.ru...

  • JavaScript中的函数

    @(javascript)[js函数] [toc] JavaScript中的函数 函数的分类与定义函数的方式 Ja...

  • JavaScript语言基础(二)

    JavaScript内置函数,这些函数都是由JavaScript语言自身提供,是JavaScript全局方法。pa...

网友评论

      本文标题:[Javascript] promisify函数

      本文链接:https://www.haomeiwen.com/subject/atdttftx.html