我有一些Javascript代码做了一些异步的东西与一些同步后处理,然后再次异步的东西(XHR – >解析XHR – >新的XHR基于第一个).我没有完成错误处理:
/* API */
function getFile(name) {
return $.ajax({
url: name + ".json"
}).then(function(data) {
return data.id
},handleError)
}
function handleError(errorObj) {
if (errorObj.status) {
return errorObj.status
} else {
return errorObj
}
}
function myApiCall() {
return getFile(1)
.then(getFile,handleError)
.then(getFile,handleError);
}
/* caller */
function failFunction(status) {
console.log("fail: ")
console.log(status)
}
myApiCall().then(function(id) {
console.log(id)
},failFunction)
1.json看起来像这样
{
"id": "2"
}
直到这里一切都很好(即使我不确定这是否是做错误处理的最佳方式).如果存在所有文件,则调用调用者的成功函数,否则调用错误函数.
但是当我的同步代码中出现一些错误时,everthing会中断
function getFile(name) {
return $.ajax({
url: name + ".json"
}).then(function(data) {
throw new Error(42) // <---------
},handleError)
}
现在我得到一个控制台输出
Error: 42
没有进一步处理,来电者不会被告知.
我尝试过类似的东西
function getFile(name) {
return $.ajax({
url: name + ".json"
}).then(function(data) {
throw new Error(42)
},handleError)
.catch(handleError)
}
但这并没有让事情变得更好.最重要的是我得到一个TypeError:$.ajax(…).then(…).catch不是一个函数
最佳答案
因为您在每个阶段处理错误而不是传播它们,所以您最终会遇到问题
编辑:
The above statement is wrong,I didn’t realise how broken jquery promises are when I wrote it – see the difference between the first block of code (Promise/A+) and the second (jQuery promise with fingers crossed behind it’s back)
相反,你可以做类似的事情:
function getFile(name) {
// wrap jquery "promise" in real Promise
// you'll need a Promise polyfill for Internet Explorer to use this method
return new Promise(function(resolve,reject) {
$.ajax({
url: name + ".json?" + Math.random()
}).then(function(data) {
resolve(data.id);
},function(err) {
reject(err);
});
});
}
function handleError(errorObj) {
//console.log(errorObj)
if (errorObj.status) {
throw errorObj.status;
} else {
throw errorObj;
}
}
function myApiCall() {
return getFile(1)
.then(getFile)
.then(getFile)
.then(getFile)
.then(getFile)
.catch(handleError);
}
function failFunction(status) {
console.log("fail: ")
console.log(status)
}
myApiCall().then(function(id) {
console.log(id);
})
.catch(failFunction);
当使用jQuery时,你的承诺就像是你用手指交叉背后的承诺
function getFile(name) {
return $.ajax({
url: name + ".json"
}).then(function(data) {
return data.id;
});
}
function handleError(errorObj) {
if (errorObj.status) {
return errorObj.status; // return in jquery!
} else {
return errorObj;
}
}
function myApiCall() {
return getFile(1)
.then(getFile)
.then(getFile)
.then(getFile)
.then(getFile)
.fail(handleError); // like jquery promises in general,use fail instead of the compliant catch
}
/* caller */
function failFunction(status) {
console.log("fail: ");
console.log(status);
}
myApiCall().then(function(id) {
console.log(id);
})
.fail(failFunction);