2017-09-14 2 views
0

Ich benutze RequireJS beim Prototyping einer Anwendung. Ich "fälsche" eine echte Datenbank, indem ich eine JSON-Datei über Ajax lade.Verwenden des Ergebnisses eines AJAX-Aufrufs als AMD-Modul

Ich habe mehrere Module, die diese JSON-Datei benötigen, die ich festgestellt habe, Ergebnisse in mehreren HTTP-Anfragen. Da ich bereits RequireJS benutze, dachte ich mir "Hey, warum lade diese JSON-Datei nicht als ein anderes Modul". Da ein Modul ein Objekt zurückgeben kann, erschien es sinnvoll.

So habe ich versucht, dies:

// 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 
}) 

ich verstehen, warum, was ich tue nicht funktioniert. Ich bin mir nicht sicher, was der beste Weg wäre, dies tatsächlich zu tun.

Dinge, die ich will nicht tun:

  • ändern getJSON zu async: false
  • eine while (data == null) {} hinzufügen, bevor Sie Daten zurückgeben

Gibt es eine AMD-y was erreichen wollen Ich versuche es zu tun? Ich bin mir sicher, dass es hier einen besseren Ansatz gibt.

bearbeiten

ich das gerade versucht. Es funktioniert, aber ich bin nicht sicher, ob dies eine gute oder schlechte Idee ist:

// 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 
}) 

Meine Sorge ist, (1) Browser-Unterstützung (dies ist ein „Versprechen“, nicht wahr?) Und (2), wenn mehrere Module tun dies zur gleichen Zeit, wird es explodieren.

+0

Die Verwendung von Versprechen ist eine gute Idee. – SLaks

+0

Meine Bearbeitung arbeitete seltsamerweise in IE, obwohl IE Versprechungen nicht unterstützt. Es sieht tatsächlich so aus, als wollte ich ein Versprechen verwenden, aber (da meine Daten in ein JQuery-Objekt gingen), wurde mit '.then()' tatsächlich JQuerys ['defered.then()'] (https: // api. jquery.com/deferred.then/) Methode, weshalb es in IE funktioniert. – Scribblemacher

+0

Ja; jQuery enthält eine eigene Versprechens-Implementierung ('Deferred') und verwendet nie native Versprechungen. – SLaks

Antwort

0

Da sich diese Frage speziell auf die Verwendung von JQuery bezieht, können Sie dies ohne ein systemeigenes Versprechen unter Verwendung von JQuerys deferred.then() tun.

// 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 
}) 

Basierend auf der Beschreibung der then() in jQuerys docs, sieht es so ein Versprechen hinter den Kulissen verwendet:

Ab jQuery 1.8, gibt die deferred.then() -Methode eine neue Versprechen, das den Status und die Werte einer durch eine Funktion verzögerten Funktion filtern kann, wobei die jetzt veraltete deferred.pipe() -Methode ersetzt wird. [...]

Rückrufe werden in der Reihenfolge ausgeführt, in der sie hinzugefügt wurden. Da deferred.than ein Promise zurückgibt, können andere Methoden des Promise-Objekts an dieses gekoppelt werden, einschließlich zusätzlicher .then() - Methoden.

Seit der JQuery .then() Arbeit in IE tut, ich denke, sie sind polyfilling das Versprechen für IE hinter den Kulissen.

Verwandte Themen