Dojo – 吞下promise的ReferenceError异常

在jQuery中,如果你在ajax回调方法中出错,你将得到一个正确的控制台错误信息和stacktrace.

$.get("https://api.github.com/users/octocat/orgs",function() {
  var a = FAIL;
});

然而,在使用dojo / request / xhr的dojo中,似乎这些愚蠢的错误正在被完全吞噬.我运行它时控制台中唯一的东西是“然后”和“总是”.

require(["dojo/request/xhr" ],function(xhr) {
    var promise = xhr.get("https://api.github.com/users/octocat/orgs");
    promise.then(function(data) {
        console.log('then');
        var a = FAIL;
        console.log('goodbye');
    },function() {
        console.log('error');
    });
    promise.otherwise(function() {
        console.log('otherwise');
    });
    promise.always(function() {
        console.log('always');
    });
});

使用已弃用的dojo.xhrGet,问题略有改善.我收到一个控制台错误消息,我的错误处理程序被调用,但它只是说“ReferenceError {}”并为我提供了一个永远不会指向我拥有的函数的堆栈跟踪:

dojo.xhrGet({
    url: "https://api.github.com/users/octocat/orgs",load: function() {
        console.log('dojo.xhrGet.load');
        var a = FAIL;

        console.log('goodbye dojo.xhrGet.load');
    },error: function() {
        console.log('dojo.xhrGet.error');
    },handle: function() {
        console.log('dojo.xhrGet.handle');
    }
});

在编写程序时我们会犯错误,很高兴我们有像Chrome开发人员工具这样的工具来指出我们的错误.当您可以看到堆栈跟踪和错误消息时,找到错误所需的时间显然比没有反馈时快得多.我在dojo中没有得到任何反馈,我无法相信这样一个受欢迎的库可以以这种方式运行.我究竟做错了什么?

解决方法

你从jQuery继承的promises的理解与其他人(检查Promises / a implementation)有着根本的不同.对于本答复的其余部分,我将谈谈承诺/合规承诺. Dojo的Deferred实际上并不合规,但它足够接近我在这里讨论的所有内容同样适用.

Promise是不可变的,你不能通过调用然后改变promises状态.承诺代表了最终的价值,能够通过说“一旦价值准备好,做到这一点”来改变承诺是没有意义的.

那么,希望这能解释为什么不调用你的错误处理程序,但是捕获错误的基本思想仍然是完全可能的.您只需要使用返回值.当你在承诺上调用它时,它会返回一个新的(几乎总是)不同的承诺.这个新的承诺非常特殊,如果解析了原始版本,并且调用了你传递的成功处理程序,并返回了一些内容,那就是第二个promise的解析值.

同样,如果触发了错误处理程序(在第一个promise上),并且该函数返回了某些内容,则该内容将成为第二个promise的解析值.对于抛出的错误也是如此,它们被传递给错误处理程序(第二个承诺!).

所以这是你的第一个代码示例,以更多的承诺/方式编写:

require(["dojo/request/xhr" ],function() {
        console.log('error');
    }).then(null,function() {
        console.log('otherwise');
    });

    promise.always(function() {
        console.log('always');
    });
});

我真的不明白你想要用always函数做什么,所以我不知道在哪里放置那个.关于调用堆栈的主题,我建议检查具有令人难以置信的高级异步调用堆栈支持的Q promise库.

相关文章

我有一个网格,可以根据更大的树结构编辑小块数据.为了更容易...
我即将开始开发一款教育性的视频游戏.我已经决定以一种我可以...
我正在使用带有Grails2.3.9的Dojo1.9.DojoNumberTextBox小部...
1.引言鉴于个人需求的转变,本系列将记录自学arcgisapiforja...
我正在阅读使用dojo’sdeclare进行类创建的语法.描述令人困惑...
我的团队由更多的java人员和JavaScript经验丰富组成.我知道这...