使用 AJAX 调用的结果作为 AMD 模块
Using the result of an AJAX call as an AMD module
我在制作应用程序原型时使用 RequireJS。通过 ajax.
加载 json 文件,我是 "faking" 一个真实的数据库
我有几个模块需要这个 json 文件,我注意到它会导致多个 http 请求。因为我已经在使用 RequireJS,所以我心想 "hey, why not load this json file as another module"。既然一个模块可以return一个对象,这似乎是合理的。
所以我尝试了这个:
// data.js
define(function(require){
const $ = require('jquery')
var data = {}
$.getJSON('/path/to/data.json', function(json_data){
data = json_data
})
// this does not work because getJSON is async
return data
})
// some_module.js
define(function(require){
const my_data = require('data')
console.log(data) // undefined, but want it to be an object
})
我明白为什么我正在做的事情不起作用。不过,我不确定实际执行此操作的最佳方法是什么。
我不想做的事情:
- 将 getJSON 更改为
async: false
- 在尝试 return 数据之前添加一个
while (data == null) {}
是否有 AMD-y 想要完成我想做的事情?我确信这里有更好的方法。
编辑
我刚刚试过了。它有效,但我不确定这是好主意还是坏主意:
// in data.js
return $.getJSON('/path/to/data.json')
// in some_module.js
const my_data = require('data')
my_data.then(function(){
console.log(my_data.responseText)
// do stuff with my_data.responseText
})
我担心的是 (1) 浏览器支持(这是 "promise",对吧?)和 (2) 如果多个模块同时执行此操作,它会爆炸吗。
因为这个问题具体指的是使用 JQuery,你实际上可以使用 JQuery 的 deferred.then()
.
// in data.js
return $.getJSON('/path/to/data.json')
// in some_module.js
const my_data = require('data') // this is a JQuery object
// using JQuery's .then(), not a promise
my_data.then(function(){
console.log(my_data.responseText)
// do stuff with my_data.responseText
})
根据 JQuery 文档中对 then()
的描述,这似乎是在幕后使用了一个承诺:
As of jQuery 1.8, the deferred.then() method returns a new promise that can filter the status and values of a deferred through a function, replacing the now-deprecated deferred.pipe() method. [...]
Callbacks are executed in the order they were added. Since deferred.then returns a Promise, other methods of the Promise object can be chained to this one, including additional .then() methods.
由于 JQuery 的 .then()
确实在 IE 中工作,我猜他们正在幕后为 IE 实现承诺。
我在制作应用程序原型时使用 RequireJS。通过 ajax.
加载 json 文件,我是 "faking" 一个真实的数据库我有几个模块需要这个 json 文件,我注意到它会导致多个 http 请求。因为我已经在使用 RequireJS,所以我心想 "hey, why not load this json file as another module"。既然一个模块可以return一个对象,这似乎是合理的。
所以我尝试了这个:
// data.js
define(function(require){
const $ = require('jquery')
var data = {}
$.getJSON('/path/to/data.json', function(json_data){
data = json_data
})
// this does not work because getJSON is async
return data
})
// some_module.js
define(function(require){
const my_data = require('data')
console.log(data) // undefined, but want it to be an object
})
我明白为什么我正在做的事情不起作用。不过,我不确定实际执行此操作的最佳方法是什么。
我不想做的事情:
- 将 getJSON 更改为
async: false
- 在尝试 return 数据之前添加一个
while (data == null) {}
是否有 AMD-y 想要完成我想做的事情?我确信这里有更好的方法。
编辑
我刚刚试过了。它有效,但我不确定这是好主意还是坏主意:
// in data.js
return $.getJSON('/path/to/data.json')
// in some_module.js
const my_data = require('data')
my_data.then(function(){
console.log(my_data.responseText)
// do stuff with my_data.responseText
})
我担心的是 (1) 浏览器支持(这是 "promise",对吧?)和 (2) 如果多个模块同时执行此操作,它会爆炸吗。
因为这个问题具体指的是使用 JQuery,你实际上可以使用 JQuery 的 deferred.then()
.
// in data.js
return $.getJSON('/path/to/data.json')
// in some_module.js
const my_data = require('data') // this is a JQuery object
// using JQuery's .then(), not a promise
my_data.then(function(){
console.log(my_data.responseText)
// do stuff with my_data.responseText
})
根据 JQuery 文档中对 then()
的描述,这似乎是在幕后使用了一个承诺:
As of jQuery 1.8, the deferred.then() method returns a new promise that can filter the status and values of a deferred through a function, replacing the now-deprecated deferred.pipe() method. [...]
Callbacks are executed in the order they were added. Since deferred.then returns a Promise, other methods of the Promise object can be chained to this one, including additional .then() methods.
由于 JQuery 的 .then()
确实在 IE 中工作,我猜他们正在幕后为 IE 实现承诺。