节点:异步版本的 readline util.promisify

Node: asynchronous version of readline with util.promisify

我正在尝试使用 promisify 创建 readline 的异步版本。

这样使用的东西:

import { Cli } from '../services/Cli';

const cli = new Cli();

const main = async () => {
  await cli.question('What is your name ? ');
  await console.log('\nBYE');

  await process.exit(0);
};

这是我的尝试:

import { promisify } from 'util';
import readline from 'readline';

export class Cli {
  private cli;

  constructor() {
    this.cli = readline.createInterface({
      input: process.stdin,
      output: process.stdout,
    });
  }

  question(text: string) {
    return promisify(this.cli.question).call(this.cli, text);
  }
}

我的灵感来自于我为 mysql 使用的其他包装器,它运行良好:

import { promisify } from 'util';
import mysql from 'mysql';
import config from '../../config.test.json';

export class MySQL {
  private mySQL;

  constructor() {

    this.mySQL = mysql.createConnection(config.database);
  }

  query(sql: string, args?: string | number | [] | {}) {
    return promisify(this.mySQL.query).call(this.mySQL, sql, args);
  }
}

// use it
this.mySQL = new MySQL();
const users = await this.mySQL.query("SELECT * FROM user");
return users

但是没有返回任何东西。有什么想法吗?

问题是由readline.question()函数的接口引起的:

The callback function passed to rl.question() does not follow the typical pattern of accepting an Error object or null as the first argument. The callback is called with the provided answer as the only argument.

Promisify works 仅限标准回调接口:

akes a function following the common error-first callback style, i.e. taking a (err, value) => ... callback as the last argument, and returns a version that returns promises.

你需要包装它:

  question (text) {
    return new Promise(resolve => {
      this.cli.question(text, resolve)
    })
  }

然后

    const name = await cli.question('What is your name ? ')
    console.log(name)