Javascript 如何使用promise处理失败的ajax请求

Javascript 如何使用promise处理失败的ajax请求,javascript,jquery,ajax,promise,Javascript,Jquery,Ajax,Promise,我提出了多个类似这样的ajax请求 imgPromises=[]; imgPromise1=$.ajax({ url:s3Url, 类型:“POST”, 数据:s3FormData, mimeType:“多部分/表单数据”, contentType:false, cache:false, processData:false }).done(功能(数据、状态、表单XHR){ x=formXHR['responseText'].toString(); var uploadedrl=x.match(

我提出了多个类似这样的ajax请求

imgPromises=[];
imgPromise1=$.ajax({
url:s3Url,
类型:“POST”,
数据:s3FormData,
mimeType:“多部分/表单数据”,
contentType:false,
cache:false,
processData:false
}).done(功能(数据、状态、表单XHR){
x=formXHR['responseText'].toString();
var uploadedrl=x.match((.*)[1];
if($(this.attr('id').startsWith('inp')){
if($(this.attr('id').startsWith('inp'))$('footer').css('background-image','url('uploadedrl+')));
footerBackground=$('footer').css('background');
}
}).fail(函数(){
log(“在ajax中失败”);
}.约束(这个);
imgPromises.push(imgPromise1);
imgPromise2=$.ajax({
url:s3Url,
类型:“POST”,
数据:s3FormData,
mimeType:“多部分/表单数据”,
contentType:false,
cache:false,
processData:false
}).done(功能(数据、状态、表单XHR){
x=formXHR['responseText'].toString();
var uploadedrl=x.match((.*)[1];
if($(this.attr('id').startsWith('inp')){
if($(this.attr('id').startsWith('inp'))$('footer').css('background-image','url('uploadedrl+')));
footerBackground=$('footer').css('background');
}
}).fail(函数(){
log(“在ajax中失败”);
}.约束(这个);
imgPromises.push(imgPromise2);

Promise.all(imgPromises.then(function(){});
您在错误的位置使用了
then

const Fail = function(error){this.error=error;};//special Fail type value
const isFail = o=>(o&&o.constructor)===Fail;//see if item passed is fail type
const isNotFail = o => !isFail(o);//see if item passed is not fail type
Promise.all(imgPromises
  .map(
    p=>Promise.resolve(p)/**convert to real promise*/
  ).map(
    p=>p.catch(error=>new Fail(error))//single request failed, resolve with Fail value
  )
)
.then(function (responses) {
  // successes = responses.filter(isNotFail)
  // failed = responses.filter(isFail)
})
.catch(function (err) {
  //handle error
});

根据您使用的jQuery版本,您可以使用
.catch
并在catch中返回承诺将使用的内容

如果任何延迟(是jQuery承诺实现)拒绝,jQuery版本的Promise.all($.when)将不会拒绝

这只是从版本3开始的,因为jQuery在这个版本之前的延迟行为不像标准化承诺(现代浏览器固有的承诺)

函数makeRequest(num){//返回$.Deferred,与$.ajax类似
var d=$.Deferred();
设置超时(()=>{
如果(num>1){//如果传递的数字大于1,则拒绝
d、 拒绝(“拒绝超过一个”);
返回;
}
d、 解析(num)
}, 10);
返回d.promise();
}
$.when.apply(//jquerys Promise.all需要apply才能传递“promises”数组
$,
[1,2]。映射(//将数字1和2映射到延迟的1将解决2个拒绝
函数(num){
返回makeRequest(num)
.catch(//catch已拒绝延迟
函数(错误){return“error in:”+num;}//使用此函数解析
);
}
)
)。然后(//两个延迟(=jQuery-promise-like)被解析
函数(){
log(“完成了”,[].slice.apply(参数));
}
)

要等待所有承诺完成其任务(解决和/或拒绝),我们
返回每个承诺的
catch()

在本例中,我们使用
.then()
来接收所有信息

我们可以使用
filterInformation
helper函数过滤被拒绝和解析的数据

示例:

const mockResolvePromise=(消息)=>{
返回新承诺((解决)=>{
解析(消息)
})
}
常量mockRejectPromise=(messageError)=>{
返回新承诺((u,拒绝)=>{
拒绝(messageError)
})
}
const ajax0=mockResolvePromise({nice:'data'})
const ajax1=mockRejectPromise(“错误”);
const ajax2=mockRejectPromise(“半坏错误”);
const ajax3=mockRejectPromise(“超级错误”);
const ajax4=mockResolvePromise({你好:'帅哥'})
const promises=[ajax0、ajax1、ajax2、ajax3、ajax4];
//现在让我们添加捕获
const promisesWithCatch=promises.map(p=>p.catch(e=>{return{error:e}))
常量过滤器信息=(填充)=>{
返回物料。减少((上一个,当前)=>{
if(current.error)返回{
…上一页,
错误:[…上一个错误,当前的错误]
};
返回{…prev,数据:[…prev.data,当前]}
},{错误:[],数据:[]})
}
全部承诺(承诺捕获)
.然后(过滤信息)
。然后(数据=>console.log(数据))

捕获被拒绝的承诺,但您有一个
承诺。所有的
都只有一个承诺,这没有多大用处…您使用的是什么版本的jQuery?您不需要承诺。所有这些都是因为IE11中没有,但您可以使用$。如果您使用的是较新版本的jQueryNote,请注意OP使用的是jQuery deferred,选项由我们决定e Promise(如果需要支持IE11,则使用polyfil)和do
Promise.resolve($.ajax)
这样下面的操作将真正起作用
Promse.all([Promise.resolve($.ajax(…).catch(resolve.description)])
选项2将使用jQuery版本3,并继续使用jQuery.Deferred而不是Promise,这样您就可以支持IE11和更旧的浏览器,而不必使用polyfill for Promise.imgpromise。imgPromises不是真正的promises,根据jQuery版本的不同,您无法捕获和解析特殊值。例如:
Promise.all(imgPromises.map(p=>p.catch(e=>new Fail(e)))。然后(总是使用拒绝承诺来解决包含失败类型的问题
这只适用于jQuery版本3或更高版本。您可以执行
Promise.all(imgPromises.map(p=>Promise.resolve(p))…
将jQuery deferred转换为real promise。如果您想支持较旧的浏览器,则可以使用jQuery版本3的deferred或使用promise polyfil并转换jQuery deferred。