Promise转换为async/await

3
我有以下代码。

class DB {
  constructor(client) {
    this.client = client;
  }
}

export default function store() {
  return new Promise((resolve, reject) => {
    pg.connect(process.env.DATABASE_URL, client => {
      client.query('CREATE TABLE x(name VARCHAR(100))');
      return resolve(new DB(client));
    });
  });
}

有没有办法将存储函数移到类构造函数内,并使用async/await进行重写?


你已经尝试过什么了吗?请展示你的代码。我们可以从那里开始讨论... - Andrea
4
我不认为这是可能的;构造函数本质上是同步的,所以你不能在构造函数内部进行异步操作(至少不能正确地执行)。 - Frxstrem
同意@Frxstrem的观点。通常构造函数应该返回新实例。你可以将store函数添加到你的类中,并在构造函数内部触发它(将promise分配给实例属性)。 - nils
async 关键字返回一个 Promise,因此与使用 Promise 没有什么不同,只是你可以通过 await 获得更好的语法糖。 - slebetman
你正在尝试解决什么问题? - a better oliver
@zeroflagL 我不知道 构造函数返回 Promise 是个坏主意。所以现在,我试图让我的代码看起来更小更易懂。现在我需要找到一种方法用 async/await 替换导出函数中的 Promise - Artem Gurzhii
2个回答

3

据我所知,您无法将构造函数声明为异步函数。但是,您可以从构造函数返回一个Promise。

这似乎是一个可怕的想法,在现实世界的情况下不要使用它。
// Define the class
class DB {
  constructor() {
    return this.store().then(client => { this.client = client; return this; });
  }

  async store() {
    const client = await new Promise((resolve) => {
      pg.connect(process.env.DATABASE_URL, resolve);
    });
    client.query('CREATE TABLE x(name VARCHAR(100))');
    return new DB(client);
  }
}

// Create an async function environment
(async function handleData() {
  const db = await new DB();
  // Do something with your DB
})();

这不会按照你的期望工作。构造函数总是返回一个实例。在构造函数中使用return语句会被忽略。 - Jordan Running
嗯,我曾经对此表示怀疑(因为即使没有Promise,结果也是一样的)。尝试使用实例属性代替:`class A { constructor() { this.name = 12; return Promise.resolve(this.name); } }(async () => { const a = await new A(); console.log(a); })();` - nils
除非我完全误解了发生的事情,否则这似乎按预期工作。或者我完全错了吗? - nils
哇,我完全没想到那个结果。抱歉我先下结论了。我用new (class { constructor() { return "foo"; } })()来测试我的断言,它返回的是匿名类的一个实例而不是 "foo", 但现在我明白这种行为只适用于基本类型;如果return值是一个对象,构造函数将返回该对象,就像你的代码一样。我需要去规范上看看具体规定是什么。顺便说一句,我不知道是谁给你的回答点了踩,但那不是我。我刚刚给你点了赞。 ;) - Jordan Running
不要从 new DB() 返回一个 promise。OP 的模式使用静态的 store 函数是完全可以的,也是应该这样结构化的。 - Bergi

1

你无法完全避免使用 Promise 构造函数,因为你需要它来将连接转换为 promise:

function connect(url) {
  return new Promise((resolve, reject) => {
    pg.connect(url, resolve);
  });
}

有了这个,你可以使用 async/await
export default async function store() {
  const client = await connect(process.env.DATABASE_URL);
  client.query('CREATE TABLE x(name VARCHAR(100))');
  return new DB(client);
}

如果你想的话,可以将该函数移入你的类中,但我看不出任何理由:

export default class DB {
  constructor(client) {
    this.client = client;
  }
  static async store() {
    const client = await connect(process.env.DATABASE_URL);
    client.query('CREATE TABLE x(name VARCHAR(100))');
    return new this(client);
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接