在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库.