使用AJAX调用的结果作为AMD模块

时间:2017-09-14 19:54:18

标签: ajax requirejs

我在为应用程序进行原型设计时使用RequireJS。我通过ajax加载一个json文件来伪造一个真正的数据库。

我有几个模块需要这个json文件,我注意到多个http请求中的结果。因为我已经在使用RequireJS,所以我自己“嘿,为什么不把这个json文件作为另一个模块加载”。由于模块可以返回一个对象,这似乎是合理的。

所以我尝试了这个:

// 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
  • 在尝试返回数据之前添加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)浏览器支持(这是“承诺”,对吗?)和(2)如果多个模块同时执行此操作,它是否会爆炸。

1 个答案:

答案 0 :(得分:0)

因为这个问题特别指的是使用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()的描述,看起来这是在幕后使用的承诺:

  

从jQuery 1.8开始,deferred.then()方法返回一个新的promise,它可以过滤通过函数延迟的状态和值,替换现在已弃用的deferred.pipe()方法。 [...]

     

回调按添加顺序执行。由于deferred.then返回一个Promise,Promise对象的其他方法可以链接到这个方法,包括额外的.then()方法。

由于JQuery的.then()确实可以在IE中运行,我猜他们正在填补IE在幕后的承诺。