dojo / Deferred链接机制不尊重异步调用

时间:2012-11-15 15:52:09

标签: asynchronous dojo callback chaining deferred

我对dojo很新,但是我在处理Deferred 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函数后出现错误消息,很明显,函数调用的值必须是未定义的,因为回调尚未完成。

我的问题是,这种对Deferred API的误解必须在我的代码中,因为目的是评估editOptionsDialog的函数调用AS SOON AS异步调用完成并调用后备,并且在此调用完成之前不要(在函数调用仍导致未定义的状态下,但我认为这是当时返回的目的)。

感谢您的帮助

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

2 个答案:

答案 0 :(得分:1)

我创造了一个小提琴来展示你想要做的事情。

基本上我从[{1}}返回延迟到editOptionsDialog_fetchData方法。 getJsonData创建另一个editOptionsDialog_fetchData,返回Deferred。在openEditor中,我将第一个editOptionsDialog_fetchData的解析连接到解析第二个Deferred

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

答案 1 :(得分:0)

通过重组代码解决了这个问题。原则上,Deferred-object似乎无法返回到不同的require子句。因此,这对我有用:

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是否故意使用此功能。