gpt4 book ai didi

javascript - 为什么 jQuery 的 Promise.reject 不起作用?

转载 作者:行者123 更新时间:2023-11-30 20:56:36 25 4
gpt4 key购买 nike

我正在使用 REST API,类似于这个 stub :Snippet 1 (Ruby on Rails 示例)。

我有经典回调的现有 jQuery 代码:Snippet 2

这是用日志执行的:

case 1:
[INFO] /api/my/action1: got rejecting signal, do not continue

case 2:
[INFO] /api/my/action1: no rejecting signal, continue
[INFO] /api/my/action2: no rejecting signal, continue
[INFO] /api/my/action3: hurrah!! we got message: Third action executed!

case 3:
[INFO] /api/my/action1: no rejecting signal, continue
[ERROR] Got error with message: Unexpected error

我想将这段代码重构为 promise:

function ajxGet(url){
return $.ajax({
url,
dataType: 'JSON'
})
}

export function makeThreeAsyncQueries(){
ajxGet('/api/my/action1')
.then(response1 => {
if(response1.do_reject_other_actions){
console.log('[INFO] /api/my/action1: got rejecting signal, do not continue');
return Promise.reject({mute: true});
}else{
console.log('[INFO] /api/my/action1: no rejecting signal, continue');
return ajxGet('/api/my/action2');
}
})
.then(response2 => {
if(response2.do_reject_other_actions){
console.log('[INFO] /api/my/action2: got rejecting signal, do not continue');
return Promise.reject({mute: true});
}else{
console.log('[INFO] /api/my/action2: no rejecting signal, continue');
return ajxGet('/api/my/action3');
}
})
.then(response3 => {
console.log('[INFO] /api/my/action3: hurrah!! we got message: ', response3.message);
})
.fail((err) => {
if(err && err.mute){
console.log('[INFO] normal chain break.');
return
}
console.info('[ERROR] Got error with message:', err.responseJSON.message);
});
}

问题是 Promise.reject({mute: true}); 不工作,我有这些日志:

[INFO] /api/my/action1: got rejecting signal, do not continue           <<-- SHOULD STOP HERE
[INFO] /api/my/action2: no rejecting signal, continue
Uncaught (in promise) Object {mute: true}
<...callstack here...>
[INFO] /api/my/action3: hurrah!! we got message: Third action executed!

最佳答案

在您的示例中,您使用的是 Promise来自 ECMAScript 2015 specification而不是 jQuery 的 Deferred类似 promise 的对象。

所以代替这一行:

return Promise.reject({mute: true});

使用这个:

return $.Deferred().reject({ mute: true }) 

完整代码示例:

function ajxGet(url){
return $.ajax({
url,
dataType: 'JSON'
})
}

export function makeThreeAsyncQueries(){
ajxGet('/api/my/action1')
.then(response1 => {
if(response1.do_reject_other_actions){
console.log('[INFO] /api/my/action1: got rejecting signal, do not continue');
return $.Deferred().reject({ mute: true })
}else{
console.log('[INFO] /api/my/action1: no rejecting signal, continue');
return ajxGet('/api/my/action2');
}
})
.then(response2 => {
if(response2.do_reject_other_actions){
console.log('[INFO] /api/my/action2: got rejecting signal, do not continue');
return $.Deferred().reject({ mute: true })
}else{
console.log('[INFO] /api/my/action2: no rejecting signal, continue');
return ajxGet('/api/my/action3');
}
})
.then(response3 => {
console.log('[INFO] /api/my/action3: hurrah!! we got message: ', response3.message);
})
// as argument here we will get jquery's xhr object on AJAX-error, or will get payload sent by $.deferred().reject
.fail((xhr) => {
if(xhr && xhr.mute){
console.log('[INFO] normal chain break.');
return
}
console.info('[ERROR] Got error with message:', xhr.responseJSON.message);
});
}

因此当后端返回时 do_reject_other_actions === true 链将中断,您将获得正确的日志:

[INFO] /api/my/action1: got rejecting signal, do not continue
[INFO] normal chain break.

or

[INFO] /api/my/action1: no rejecting signal, continue
[INFO] /api/my/action2: got rejecting signal, do not continue
[INFO] normal chain break.

or

[INFO] /api/my/action1: no rejecting signal, continue
[INFO] /api/my/action2: no rejecting signal, continue
[INFO] /api/my/action3: hurrah!! we got message: Third action executed!

or

[INFO] /api/my/action1: no rejecting signal, continue
[ERROR] Got error with message: Unexpected error

解决方案 2

如果你想使用ECMAScript2015 Promise , 你可以把 jQuery 的 ajax 包装成 Promise :

function ajxGet(url){
return new Promise((resolve, reject) => {
$.ajax({
url,
dataType: 'JSON',
success: response => resolve(response),
error: (xhr) => { reject(xhr) },
})
});
}

export function makeThreeAsyncQueries(){
ajxGet('/api/my/action1')
.then(response1 => {
if(response1.do_reject_other_actions){
console.log('[INFO] /api/my/action1: got rejecting signal, do not continue');
return Promise.reject({mute: true});
}else{
console.log('[INFO] /api/my/action1: no rejecting signal, continue');
return ajxGet('/api/my/action2');
}
})
.then(response2 => {
if(response2.do_reject_other_actions){
console.log('[INFO] /api/my/action2: got rejecting signal, do not continue');
return Promise.reject({mute: true});
}else{
console.log('[INFO] /api/my/action2: no rejecting signal, continue');
return ajxGet('/api/my/action3');
}
})
.then(response3 => {
console.log('[INFO] /api/my/action3: hurrah!! we got message: ', response3.message);
})
.catch((xhr) => {
if(xhr && xhr.mute){
console.log('[INFO] normal chain break.');
return
}
console.info('[ERROR] Got error with message:', xhr.responseJSON.message);
});
}

请注意,您需要在链的末尾使用 catch(...) 而不是 fail(...),因为 fail是 jQuery Deferred 的方法。

关于javascript - 为什么 jQuery 的 Promise.reject 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47598520/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com