1

我对 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 的函数调用,而不是在此调用完成之前(在函数调用仍然导致未定义的状态,但我认为这是 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);
        });
    }
4

2 回答 2

1

我创建了一个小提琴来展示你想要做什么。

基本上我将 Deferred 返回到editOptionsDialog_fetchDatagetJsonData. editOptionsDialog_fetchData创建另一个Deferred它返回到openEditor. 在editOptionsDialog_fetchData中,我将第一个Deferred的解析连接到第二个的解析Deferred

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

于 2012-11-15T16:18:25.470 回答
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故意的。

于 2012-11-17T11:13:07.933 回答