0

卷曲 0.7.3

我从这里得到了一些 AMD/CommonJS 适配器代码: 同时支持 CommonJS 和 AMD

(function (name, definition) {
      if (typeof module != 'undefined') {
        module.exports = definition();
      }
      else if (typeof define == 'function' && typeof define.amd == 'object') {
        define(name, [], definition);
      }
      else {
        this[name] = definition();
      }
    }('modXyz', {
          sayHi:function (name) {
            console.log('Hi ' + name + '!');
          }
        }
    ));

我想将该代码与Curl一起使用,以使我的所有代码与 AMD/CommonJS 兼容。我期望能够做到的是:

greeter = curl(['modXyz']); 
greeter.sayHi("Gracie"); 

但是curl返回的对象不是我期望的对象。我能得到的最接近的是:

curl(['modXyz'], function(mod) { window.greeter = mod; }); 
greeter.sayHi("Gracie");

这似乎违背了 AMD 的目的。curl 有能力做这样的事情吗?我必须使用require.js来实现它吗?

4

3 回答 3

1

因为浏览器远离它的资源,它要么在获取这些资源时阻塞主线程,要么必须异步获取它们。由于我们不应该阻塞主线程(实际上使浏览器无响应),我们必须异步获取资源。(任何 AMD loader、RequireJS、dojo 等都一样)

因此,像下面这样的事情是行不通的:

var foo = require('lib/foo');

好吧,它不能在您可能习惯于在浏览器中使用的通常的全局空间中工作。但是,它可以在受控环境中工作,例如在 AMD 模块内部。

第 1 步:在模块内编写代码。

第 2 步:编写一个引导模块来启动您的应用程序。

<script src="lib/curl/src/curl.js"><script>
<script src="myapp/run.js"><script>

在 run.js 内部:

// curl 0.7.x requires a named module here ('myapp/run')
define('myapp/run', ['curl'], function (curl) {
    curl.config(
        baseUrl: '',
        packages: [ /* configure your 3rd-party packages */ ],
        paths: { /* configure any non-package 3rd-party libs here */ },
        preloads: [ /* put modules that *must* be loaded first here (e.g. shims) */ ],
        main: 'myapp/main'
    });
});

“myapp/main”可能看起来像这样:

define(function (require) {
    var view1 = require('myapp/view1/controller');
    view1.render();
    view1.placeAt('body');
});

在主模块(或任何 AMD 模块)内部,require行为更像我认为您所期望的。请注意,这是一个特殊的 AMD 签名。您不能在 中指定依赖项define并期望 具有这样的require行为。您必须仅以一种方式指定您的依赖项。这将不起作用:

define(['myapp/view1'], function (view1) {
    var foo = require('foo');
});

希望这可以帮助。

- 约翰

于 2013-02-20T16:20:24.580 回答
1

CurlJS 和 RequireJS 都支持 AMDCommonJS 的 require 调用模式:

CJS 和 AMD 之间的区别在于使用 Array 作为依赖项列表的包装器。另请注意,在 CurlJS 的配置中,您可以使用别名curlrequire使您的代码与 AMD 规范完全兼容。观察:

CJS 需要调用模式:

var a = require('name')

只有CurlJS AMD 需要调用模式:

var promise = require(['name'])
promise.then(callbackFunction)

这通常可以缩短为:

require(['name']).then(callbackFunction)

注意,CurlJS 返回一个 Promise 对象不是 AMD 规范的一部分。AMD 规范似乎没有规定 AMD 风格的 require 调用的返回值。

RequireJS 和 CurlJS 都支持标准的 AMD 要求调用模式:

require(['name'], callbackFunction)

同样,请注意使用 Array 作为标志,这是 AMD 风格的要求。这会触发返回值的不同逻辑。

为了让你的东西按你的意愿工作,在 CurlJS 上,你的代码必须在一个被包装的模块中,就像它是一个 CommonJS 模块一样,使用:

define(function(require) { ... });

有人告诉我,在这种情况下,require你得到的行为类似于 CommonJS 风格require- 同步。实际上,幕后发生的事情是加载器扫描工厂函数以查找您需要的东西,并将它们折叠到该定义的需求列表中。然后,在工厂内部,您可以执行以下操作:

var greeter = require('modXyz'); 
greeter.sayHi("Gracie");

请注意,“同步”行为仍然是一种错觉,因为实际发生的是预加载检测到的所需资源。

在 RequireJS 上,甚至 globalrequire也可以称为 CJS style: var resource = require('resource/path'),但前提是您之前已经加载了它。

换句话说,在工厂函数运行之前,CurlJS 和 RequireJS 中的加载总是异步进行的,但是在 RequireJS 中,您几乎可以在任何地方使用它,而在 CurlJS 中,这是非常小众的场景。

于 2013-02-14T07:33:56.203 回答
0

curl 函数是异步的,并返回一个承诺。因此,您只能将结果作为传递给 curl 的回调,或者通过传递给 then 的回调(一旦 promise 被实现就调用。

curl(['dep1', 'dep2', 'dep3' /* etc */], callback);

或者

curl(['dep1', 'dep2', 'dep3' /* etc */])
    .then(callback, errorback);
于 2013-02-14T00:50:54.063 回答