Dojo - xhrPut 中的变量赋值发生得太晚

Dojo - variable assignment occurs too late in xhrPut

我有以下内容:

if(typeof searchDOM === "undefined"){
    dojo.xhrPut({
        url: addrPath + "/ContServlet?mod=1&act=23",
        handleAs: "xml",
        timeout: xhrTimeout(TIMEOUT_LRG),
        load: function(dom, ioArgs){
            if(dom instanceof Error){
                console.error(dom);
            } else{
                cacheDOM = dom;
            }
        },
         error: function(response, ioArgs){
             xhrError(ioArgs, methodName);
         }
    });    
}

变量 cacheDOM 是在另一个脚本的其他地方声明(但未初始化)的全局变量。它是一个包含整个 dom 的 xml 文档,它被传递到:

问题是,当 cacheDOM 到达 fetchXml 时,它是未定义的,这会导致函数下方的 selectNode 等方法出现问题。

我没有太多接触过 xhr 调用,或者 deferreds 或 promises 之类的东西,但我认为他们可能会对此有所帮助。我该如何编写代码,以便只有在为 cacheDOM 分配了 dom 的值时,该块所在的方法的其余部分才会执行?或者如果延迟是答案,我将如何将它们合并到此代码中?我使用的dojo版本是1.7.8

好吧,问题确实是您使用的是异步的 XHR 请求。因此,fetchXml 函数必须等到该请求完成。

有几种方法可以做到这一点,您可以从 dojo.xhrPutload 函数中调用 fetchXml 函数,但这并不是一个很好的解决方案,当您的项目增长是因为它彼此之间产生了很多依赖关系。

于是,一些聪明人创造了一个API来解决异步请求,叫做promises/deferreds。

因此,您要做的是将新的 deferred 分配给 cacheDOM,例如:

require(["dojo/_base/Deferred"], function(Deferred) {
    cacheDOM = new Defered();
});

然后,在 fetchXml() 代码中,您必须稍微更改代码才能执行此操作:

function fetchXml() {
    cacheDOM.then(function(realCache) {
       console.log(realCache); 
    });
}

因此,您不能直接使用 cacheDOM,而是必须使用 cacheDOM.then() 等待它。它会在解决后触发回调,并且数据将在 realCache.

中可用

另一种方法是在 XHR 请求触发时调用整个 fetchXml 函数:

cacheDOM.then(fetchXml);

function fetchXml(cacheDOM) {
    // Work with cacheDOM
}

根据 cacheDOM.

fetchXml 函数的依赖程度,这可能需要更少的工作和更少的改动

最后,在您的 dojo.xhrPut 中,您必须执行以下操作:

cacheDOM.resolve("My data");

其中 "My data" 是您要放入 cacheDOM 的实际数据。

演示:http://jsfiddle.net/rf20s9hb/1/