Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

addSingleton cannot support async function #710

Closed
cuyl opened this issue Apr 1, 2017 · 2 comments
Closed

addSingleton cannot support async function #710

cuyl opened this issue Apr 1, 2017 · 2 comments

Comments

@cuyl
Copy link
Contributor

cuyl commented Apr 1, 2017

  • Egg Version: 1.0.0

你好:
我想写个oracledb的插件,但是想给addSingleton传一个async函数,因为async function返回的是promise,所以如下的代码获取到的app.oracle就是一个Promise。

// app.js
const oracledb = require('oracledb');

module.exports = app => {
  app.addSingleton('oracle', createOnePool);
};

async function createOnePool(config, app) {
  return await oracledb.createPool(config);
}

我找到了源代码,发现我传入的函数在singleton.init()中执行
暂时我只能把这个init函数改成async函数来解决问题
lib/core/singleton.js#L19

async init() {
    const options = this.options;
    assert(!(options.client && options.clients),
      `eggg:singleton ${this.name} can not set options.client and options.clients both`);

    // alias app[name] as client, but still support createInstance method
    if (options.client) {
      const client = await this.createInstance(options.client); // await
      this.app[this.name] = client;
      assert(!client.createInstance, 'singleton instance should not have createInstance method');
      client.createInstance = this.createInstance.bind(this);
      return;
    }

    // multi clent, use app[name].getInstance(id)
    if (options.clients) {
      for (const id in options.clients) {
        this.clients.set(id, await this.createInstance(options.clients[id])); // await
      }
      this.app[this.name] = this;
      return;
    }

    // no config.clients and config.client
    this.app[this.name] = this;
  }

请问这个init函数能否改成async函数,如果不行是否有别的解决方案。

谢谢

@dead-horse
Copy link
Member

addSingleton 设计的时候并没有考虑支持异步获取的形式,可以考虑不通过 addSingleton 来实现,而是在 app.js 中来实现这个功能:

// app.js

module.exports = app => {
  // 此处可以用 async function
  app.beforeStart(function* () {
    app.oracle = yield oracledb.createPool(app.config.oracle);
  });
}

@cuyl
Copy link
Contributor Author

cuyl commented Apr 1, 2017

谢谢,看来最简单的方法就是这样了
参考了一下egg-mysql用的ali-rds,看来得在外面封装一层才能用addSingleton

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants