使用带有回调函数的异步JavaScript尝试/捕获块
我有一段代码:使用带有回调函数的异步JavaScript尝试/捕获块,javascript,error-handling,Javascript,Error Handling,我有一段代码: function backgroundReadFile(url, callback) { var req = new XMLHttpRequest(); req.open("GET", url, true); req.addEventListener("load", function() { if (req.status < 400) callback(req.responseText); }); req.send(null); }
function backgroundReadFile(url, callback) {
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.addEventListener("load", function() {
if (req.status < 400)
callback(req.responseText);
});
req.send(null);
}
try {
backgroundReadFile("example/data.txt", function(text) {
if (text != "expected")
throw new Error("That was unexpected");
});
} catch (e) {
console.log("Hello from the catch block");
}
这很好。但是,有人告诉我:
在代码中,由于
调用backgroundReadFile
会立即返回。控制然后离开
try
块,在
稍后
问题是:为什么其他错误不会在这里被发现?当我们有连接问题,或者文件不存在时?在我看来,如果
req.addEventListener("load")
例如,不会触发。但它仍然存在-我仍然得到相同的错误-错误:这是意外的(第13行)
这意味着什么——“由于对backgroundReadFile
的调用立即返回,因此不会捕获异常”
谢谢。您的
backgroundReadFile
函数有两部分:同步部分和异步部分:
function backgroundReadFile(url, callback) {
var req = new XMLHttpRequest(); // Synchronous
req.open("GET", url, true); // Synchronous
req.addEventListener("load", function() { // Synchronous
if (req.status < 400) // *A*synchronous
callback(req.responseText); // *A*synchronous
});
req.send(null); // Synchronous
}
…您可以这样使用:
function backgroundReadFile(url) {
return new Promsie(function(resolve, reject) {
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.addEventListener("load", function() {
if (req.status < 400) {
resolve(req.responseText);
} else {
reject(new Error({status: req.status}));
});
req.addEventListener("error", reject);
req.send(null);
});
}
backgroundReadFile(url)
.then(function(text) {
// Use the text
})
.catch(function(err) {
// Handle error
});
但是在XMLHttpRequest
的特定情况下,您可以使用,这已经为您提供了一个承诺:
function backgroundReadFile(url) {
return fetch(url).then(response => {
if (!response.ok) {
throw new Error({status: response.status});
}
return response.text();
});
}
backgroundReadFile
函数有两个部分:同步部分和异步部分:
function backgroundReadFile(url, callback) {
var req = new XMLHttpRequest(); // Synchronous
req.open("GET", url, true); // Synchronous
req.addEventListener("load", function() { // Synchronous
if (req.status < 400) // *A*synchronous
callback(req.responseText); // *A*synchronous
});
req.send(null); // Synchronous
}
…您可以这样使用:
function backgroundReadFile(url) {
return new Promsie(function(resolve, reject) {
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.addEventListener("load", function() {
if (req.status < 400) {
resolve(req.responseText);
} else {
reject(new Error({status: req.status}));
});
req.addEventListener("error", reject);
req.send(null);
});
}
backgroundReadFile(url)
.then(function(text) {
// Use the text
})
.catch(function(err) {
// Handle error
});
但是在XMLHttpRequest
的特定情况下,您可以使用,这已经为您提供了一个承诺:
function backgroundReadFile(url) {
return fetch(url).then(response => {
if (!response.ok) {
throw new Error({status: response.status});
}
return response.text();
});
}
下面是代码中发生的情况的逐步分解
backgroundReadFile
,其中包含两个参数:“example/data.txt”
,以及一个匿名函数backgroundReadFile
创建AJAX请求并调用send()
。这里是异步概念发挥作用的地方:实际的HTTP请求不是立即发送的,而是放置在一个队列中,在浏览器运行完当前正在运行的任何代码(即try-ctach块)后立即执行backgroundReadFile
就此结束。执行返回到try-catch块onload
事件处理程序——不管响应是什么(即成功还是错误)backgroundReadFile
的匿名函数将作为onload
事件处理程序的一部分调用,并抛出错误。但是,正如您现在看到的,您的代码不再位于try-catch块中,因此它没有被捕获
此外,AJAX请求中的错误处理有两个方面:连接错误和服务器端错误。连接错误可以是请求超时或发送请求时可能发生的其他随机错误;这些可以分别在
ontimeout
和onerror
事件处理程序中处理。但是,如果HTTP请求发送到服务器并收到响应,那么就XMLHttpRequest
而言,请求是成功的。例如,您可以检查XMLHttpRequest
的status
属性(该属性包含HTTP响应代码,例如200表示“OK”,404表示“not found”,等等),并确定它是否算成功。下面是代码中发生的情况的逐步细分
backgroundReadFile
,其中包含两个参数:“example/data.txt”
,以及一个匿名函数backgroundReadFile
创建AJAX请求并调用send()
。这里是异步概念发挥作用的地方:实际的HTTP请求不是立即发送的,而是放置在一个队列中,在浏览器运行完当前正在运行的任何代码(即try-ctach块)后立即执行backgroundReadFile
就此结束。执行返回到try-catch块onload
事件处理程序——不管响应是什么(即成功还是错误)backgroundReadFile
的匿名函数将作为onload
事件处理程序的一部分调用,并抛出错误。但是,正如您现在看到的,您的代码不再位于try-catch块中,因此它没有被捕获
ontimeout
和onerror
事件处理程序中处理。但是,如果HTTP请求发送到服务器并收到响应,那么就XMLHttpRequest
而言,请求是成功的。例如,您可以检查XMLHttpRequest
的status
属性(其中包含HTTP响应代码,例如200表示“OK”,404)