Возврат данных из обратного вызова JSONP

У меня есть класс, который извлекает данные jsonp. Я хотел бы просто вернуть значение, но не могу этого сделать. Обратный вызов не обновляет свойство класса - не уверен, что это проблема времени или области действия.

Ext.define("App.ContentManager", {
    extend: "Ext.util.Observable",
    singleton: true,

    data: 'empty',
    getData: function() {
        this.doLoad();
        console.log(a.data) //not correct - shows original value
        return this.data;

    },
    doLoad: function(url) {
        var a = this;
        Ext.util.JSONP.request({
            url: "http://example.com/somejson",
            callbackKey: "callback",
            callback: function(c) {
                a.data = c;
                console.log(a.data) //correct json data is here
            }
        })
    },
});

person cyberwombat    schedule 10.11.2011    source источник
comment
обратный вызов является асинхронным, поэтому a.data не возвращается сразу после вызова doLoad.   -  person Joe    schedule 11.11.2011


Ответы (2)


Конечно, это вопрос времени. С doLoad() в функции getDate вы просто запускаете запрос и не ждете его завершения, чтобы данные были готовы в следующей строке. У вас есть готовые данные только в callback: function метода doLoad. Поэтому все, что вам нужно сделать, лучше всего отправить запрос в одной функции, а затем в callback:function иметь функцию, которая будет использовать возвращенные данные.

Обновить

Также я только что заметил, что это тоже проблема с областью действия. Вы кричите, что передаете область в запросе JSONP, добавляя

          url: "http://example.com/somejson",
        scope: this,    //this line
  callbackKey: "callback",

И затем в getDate вы должны: this.data так как a является локальной переменной в методе doLoad.

person ilija139    schedule 11.11.2011
comment
Спасибо - я отмечу этот ответ как правильный, так как он первый - в итоге я загрузил свой json в своем представлении sencha и применил его к html - person cyberwombat; 12.11.2011

Как отмечено в существующих комментариях, поскольку метод doLoad извлекает данные асинхронно, невозможно вернуть результат непосредственно из вызова метода. Ваши два варианта:

  • Определите свой метод с параметром обратного вызова (обычно это делается в самом Ext), чтобы внутри обратного вызова JSONP вы выполняли переданную функцию обратного вызова, передавая возвращенные данные.
  • Определите пользовательское событие, которое ваш класс может запустить из обратного вызова JSONP, передав данные в качестве аргумента события. Это было бы более подходящим в случае, когда несколько компонентов могут быть заинтересованы в результате вызова JSONP.

Или вы могли бы даже сделать оба (непроверенные):

doLoad: function(options) {
    var me = this;

    Ext.util.JSONP.request({
        url: options.url,
        scope: me,
        callbackKey: "callback",

        callback: function(data) {
            me.fireEvent('dataloaded', me, data);
            if (options.callback) {
                options.callback.apply(options.scope || me, [data]);
            }
        }
    })
}
person Brian Moeskau    schedule 11.11.2011