dojo/механизм отложенной цепочки, не учитывающий асинхронный вызов

Я новичок в додзё, но у меня есть определенная ошибка, связанная с отложенным API, я не могу помочь

мой код вызова

function openEditor(id, fieldName) {
    editOptionsDialog_fetchData(id, fieldName).then(function(data){
    console.log("done!");
    });
    console.log("leaving openEditor!");
}

который вызывает эту функцию

function editOptionsDialog_fetchData(id, fieldName) {
    require(["dojo/ready", "dojo/data/ObjectStore", "dojo/Deferred"], function(ready,     ObjectStore, Deferred) {
        var store;
        var def;

        switch (fieldName) {
            case "degree":
                store = new degreeStore();
                def = store.getJsonData();
                break;
            case "faculty":
                store = new facultyStore();
                def = store.getJsonData();
                break;
            default:
                console.log("error in editOptionsDialog_fetchData: " + fieldName);
        }

        return def.then(function(data){
            store.data = data.items;
            editOptionsDialog_select.setStore(new ObjectStore({ objectStore : store }));
            editOptionsDialog_select.store.query({ "id" : id });
            editOptionsDialog_select.startup();
        });
    });
}

где store.getJsonData() создает Deferred, который я хочу использовать для цепочки разрешения Deferred (см. дополнительный код после основного текста).

Ошибка, которую я получаю,

editOptionsDialog_fetchData(id, fieldName).then(function(data)...) is undefined

Поскольку сообщение об ошибке появляется сразу после обращения к функции openEditor, понятно, что значение вызова функции должно быть неопределенным, поскольку обратный вызов еще не выполнен.

Мой вопрос заключается в том, где это непонимание отложенного API должно быть в моем коде, поскольку цель состоит в том, чтобы оценить вызов функции editOptionsDialog КАК ТОЛЬКО асинхронный вызов будет выполнен и вызван, А НЕ ДО того, как этот вызов завершится (в состояние, в котором вызов функции по-прежнему приводит к неопределенности, но я думал, что это и есть цель then-return).

Спасибо за вашу помощь

--- дополнительный код для getJsonData() ---

getJsonData: function() {
        return xhr(this.handlerUrl, {
            handleAs: "json",
            method: "POST",
            data: {
                action: "getJsonData"
            }
        }).then(function(data){
            return data;
        }, function(err){
            alert("Data cannot be fetched in degreeStore.getJsonData! " + err);
        });
    }

person Giehl Man    schedule 15.11.2012    source источник


Ответы (2)


Я создал скрипку, чтобы продемонстрировать, что вы пытаетесь сделать.

В основном я возвращаю Deferred методу editOptionsDialog_fetchData из getJsonData. editOptionsDialog_fetchData создает еще один Deferred, который возвращается в openEditor. В editOptionsDialog_fetchData я соединяю разрешение первого Deferred с разрешением второго Deferred.

http://jsfiddle.net/cswing/yUTT8/

person Craig Swing    schedule 15.11.2012
comment
Танки для этого завершения. В вашем случае пример работает абсолютно идеально. Но одна вещь, которую я не упомянул явно, заключалась в том, что функция openitor находится в отдельном предложении require, чем подпрограмма fetchdata. В любом случае это не дает мне понять, почему вызов fetchData происходит слишком рано и, таким образом, не возвращает отложенный... что приводит к тому, что метод then не обрабатывается. - person Giehl Man; 16.11.2012

Решил проблему реструктуризацией кода. В принципе, объект Deferred, по-видимому, не может быть возвращен в отдельное требование. Поэтому это сработало для меня:

var editMultilanguageDialog_Startup;
// one require-clause, wrapping all the Deferred-sensitive statements
require(["dojo/request/xhr", "dojo/json", "dojo/Deferred", "dojo/store/Memory", "dojox/timing", "dojo/domReady!"], function(xhr, json, Deferred, Memory, timing, domReady) {

   function editMultilanguageDialog_Startup(id, fieldName) {
    // code from former mainForm -> moved into this require-clause
    //[...]
    // here, the invocation is no longer undefined and waits for the resolve        
    editMultilanguageDialog_fetchData(id, fieldName).then(function(data){
            //[...]
            editMultilanguageDialog.show(); 
        });    
    }

    function editMultilanguageDialog_fetchData(id, fieldName) {
        // unchanged, returns Deferred
    }

}); 

Это обходной путь, я не знаю, предназначена ли эта функция специально для dojo.

person Giehl Man    schedule 17.11.2012