3

假设我有一个 AMD 模块,它在某些环境中有条件地需要第二个模块:

定义([“要求”],功能(要求){
  变量 myObj = {
    富:console.error.bind(控制台)
  };
  如果(浏览器环境)
    要求([“./条件-polyfill”],函数(polyfill){
      myObj.foo = console.log.bind(console,polyfill) ;
    });
  返回我的对象​​;//在满足条件要求之前返回
});

问题是:在条件要求完成后,如何延迟 define() 调用以返回/回调?

即下面的代码失败:

需要([“模块从上面”],函数(记录器){
  logger.foo("你好!"); //console.error 被调用
});

我对解决这个问题的想法:

  • 如果我 inline ./polyfill,一切都会奏效。但是,这只是规避了问题,并不适用于所有情况。我希望它模块化是有原因的。
  • 我可以返回一个Deferred对象,而不是稍后myObj实现。./conditional-polyfill这会起作用,但是一直打电话真的很难看loggerDeferred.then(function(logger){ ... });
  • 我可以为这个模块制作一个 AMD 加载器插件。一切准备就绪后立即调用回调。同样,这会起作用,但自己的加载器插件不适用于我的构建工具。

我能想到的所有解决方案都是黑客而不是好的代码。但是,我认为我的问题并不太牵强。那么,如何处理呢?

4

2 回答 2

3

将条件推送到“工厂函数”之外(AMD 社区中常用的名称,指的是 require 和 define 的回调函数)

;(function() {

function factory(require, polyfill){
  var myObj = { 
    foo: console.error.bind(console) 
  }
  if(polyfill){
    myObj.foo = console.log.bind(console, polyfill)
  }
  return myObj
}

var need = ['require']

if(browserEnv){
  need.push("./conditional-polyfill")
}

define(need, factory)

})();
于 2013-01-15T19:33:23.540 回答
0

正如你所说,我会使用延迟。

延迟模式是此类问题的理想解决方案,因为它允许您以一致的方式将复杂的异步操作联系在一起。

它会使您的代码更大一些,但与修改加载器和构建工具相比,它是一个简单的解决方案。

于 2013-01-15T15:46:51.993 回答