在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中没有得到任何反馈,我无法相信这样一个受欢迎的库可以以这种方式运行。我做错了什么?
答案 0 :(得分:4)
在dojoConfig中设置useDeferredInstrumentation:true。这是an example。
<script>
var dojoConfig = {
useDeferredInstrumentation: true
};
</script>
<script src="js/lib/dojo/dojo.js.uncompressed.js"></script>
这在console.error上提供了一个相当实用的错误消息和stacktrace输出:
ReferenceError {} "ReferenceError: FAIL is not defined
at http://fiddle.jshell.net/gNdCb/2/show/:25:17
at signalListener (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14205:21)
at signalWaiting (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14196:4)
at resolve (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14360:5)
at signalDeferred (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14249:15)
at signalListener (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14220:6)
at signalWaiting (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14196:4)
at resolve (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14360:5)
at signalDeferred (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14249:15)
at signalListener (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14226:4)
----------------------------------------
rejected at signalDeferred (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14252:15)
at signalListener (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14223:5)
at signalWaiting (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14196:4)
at resolve (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14360:5)
at signalDeferred (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14249:15)
at signalListener (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14220:6)
at signalWaiting (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14196:4)
at resolve (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14360:5)
at signalDeferred (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14249:15)
at signalListener (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14226:4)
----------------------------------------
Error
at Promise.then.promise.then (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14420:24)
at http://fiddle.jshell.net/gNdCb/2/show/:23:13
at runFactory (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:1117:43)
at execModule (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:1245:5)
at http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:812:7
at guardCheckComplete (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:1260:5)
at contextRequire (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:811:6)
at req (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:137:11)
at http://fiddle.jshell.net/gNdCb/2/show/:21:1"
答案 1 :(得分:4)
你从jQuery继承的promises的理解与其他人(检查Promises / a + implementation)有着根本的不同。对于本答复的其余部分,我将讨论承诺/符合承诺的承诺。 Dojo的Deferred实际上不是+兼容的,但它足够接近我在这里讨论的所有内容同样适用。
Promise是不可变的,你不能通过调用then
来改变promises状态。承诺代表了最终的价值,能够通过说“一旦价值准备好,做到这一点”来改变承诺是没有意义的。
那么,希望这能解释为什么不调用你的错误处理程序,但是捕获错误的基本思想仍然是完全可能的。您只需要使用返回值。当您在承诺上调用then
时,它会返回一个新的(几乎总是)不同的承诺。这个新的承诺非常特殊,如果解析了原始版本,并且调用了你传递的成功处理程序,并返回了一些内容,那就是第二个promise的解析值。
同样,如果触发了错误处理程序(在第一个promise上),并且该函数返回了某些内容,则该内容将成为第二个promise的解析值。对于抛出的错误也是如此,它们被传递给错误处理程序(第二个承诺!)。
所以这是你的第一个以更多承诺/ a +方式编写的代码示例:
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');
}).then(null, function() {
console.log('otherwise');
});
promise.always(function() {
console.log('always');
});
});
我真的不明白你想要用always函数做什么,所以我不知道在哪里放置那个。关于调用堆栈的主题,我建议检查具有令人难以置信的高级异步调用堆栈支持的Q promise库。
答案 2 :(得分:0)
我有非常具体的需求,因为我需要异常来点击浏览器实现的本地catch子句。没关系为什么我需要这个,但是我使用了这样的东西:
function scream(func) {
return function() {
var args = arguments;
setTimeout(function(){
func.apply(null, args);
}, 0);
};
}
然后,使用它
var promise = xhr.get("https://api.github.com/users/octocat/orgs");
promise.then(scream(function(data) {
//do stuff
}));
通过使用setTimeout,您可以在browsers事件队列中执行该函数,从而使dojo无法吞下您的异常。但是,一般来说这是一个糟糕的解决方案,因为:
无论如何,我只是将它作为选项提出。