带有异步初始化的单例模式

10

我有一个使用场景,其中一个Singleton对象在其初始化过程中包含异步步骤。此Singleton的其他公共方法依赖于初始化步骤设置的实例变量。我该如何将异步调用转换为同步调用?

var mySingleton = (function () {

  var instance;

  function init() {

    // Private methods and variables
    function privateMethod(){
      console.log( "I am private" );
    }

    var privateAsync = (function(){
      // async call which returns an object
    })();

    return {

      // Public methods and variables

      publicMethod: function () {
        console.log( "The public can see me!" );
      },

      publicProperty: "I am also public",

      getPrivateValue: function() {
        return privateAsync;
      }
    };
  };

  return {

    // Get the Singleton instance if one exists
    // or create one if it doesn't
    getInstance: function () {

      if ( !instance ) {
        instance = init();
      }

      return instance;
    }

  };

})();

var foo = mySingleton.getInstance().getPrivateValue();

我应该如何使异步调用同步?- 这是不可能的。 - Jaromanda X
1
免责声明:单例模式很糟糕。不要使用它们,它们解决不了任何问题 - 只需使用常规对象并传递它。该对象的方法应返回一个可链接初始化步骤的 Promise。 - Benjamin Gruenbaum
@BenjaminGruenbaum - 好的...那你能解释一下为什么你这么说吗?... - nf071590
@nf071590 http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/ - Benjamin Gruenbaum
@BenjaminGruenbaum - 嗯... 你意识到这是一个Java示例的链接,而这个Stack Overflow问题是关于JavaScript的吗?所以很抱歉,我不能理解你的观点... 而且在那个示例中,他们只是有一些引用其他类(或依赖于...)的类(没有任何交叉引用彼此的文档),我不认为那就是单例模式... 如果我错了,请纠正我 - 我不是一个Java专家(或单例模式)。 - nf071590
显示剩余3条评论
1个回答

4
如果您真的想使用IIFE创建类似单例的方法,仍然需要使用承诺或回调来处理异步调用,并与它们一起工作,而不是尝试将异步转换为同步。类似以下代码:
var mySingleton = (function() {

  var instance;

  function init() {
    // Private methods and variables
    function privateMethod() {
      console.log("I am private");
    }

    var privateAsync = new Promise(function(resolve, reject) {
          // async call which returns an object
        // resolve or reject based on result of async call here
    });

    return {
      // Public methods and variables
      publicMethod: function() {
        console.log("The public can see me!");
      },
      publicProperty: "I am also public",
      getPrivateValue: function() {
        return privateAsync;
      }
    };
  };

  return {

    // Get the Singleton instance if one exists
    // or create one if it doesn't
    getInstance: function() {

      if (!instance) {
        instance = init();
      }

      return instance;
    }

  };

})();

var foo = mySingleton.getInstance().getPrivateValue().then(function(result) {
   // woohoo
}).catch(function(err) {
    // epic fail
})

我会尝试这个方法,以及上面评论中提到的另一种方法。 - johnborges

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