我有一个返回AJAX承诺的现有函数。我想更新此函数以在运行AJAX调用之前显示确认警报,但代码的其他部分使用此函数并且已经期待一个承诺。
这是我原来的功能:
function doTheDeed() {
return $.ajax({
url: '/api/delete/123',
method: 'POST'
}).done(function () {
alert('The deed is done.');
});
}
doTheDeed().done(function {} { /*Do something else*/ });
现在我想在运行AJAX调用之前与用户确认。如何维护返回承诺的API协议,同时等待用户确认或取消?
function doTheDeed() {
bootbox.confirm('Are you sure?', function (result) {
if (result) {
// Too late to return a promise, promise should've been returned a long time ago
return $.ajax({
url: '/api/delete/123',
method: 'POST'
}).done(function () {
alert('The deed is done.');
});
} else {
//return what??
}
});
}
doTheDeed().done(function {} { /*Do something else*/ });
我是否需要根据用户的回复有条件地返回不同的承诺?
答案 0 :(得分:3)
您可以使用jQuery的Deferreds吗?
function doTheDeed() {
var def = $.Deferred();
bootbox.confirm('Are you sure?', def.resolve);
return def.promise().then(function(result) {
return result ? $.post('/api/delete/123') : "no go";
});
}
doTheDeed().done(function (data) {
if (data == 'no go') {
// user declined
} else {
// item deleted
}
}).fail(function(err) {
// something failed
});
答案 1 :(得分:2)
基于Adeneo的回答,并坚持最低级别的promisifying原则,bootbox可以通过bootbox.confirm()
的可重用承诺进行monkeypatched,而不必侵入bootbox本身。
如果你这样做,那就合适了:
if(!bootbox.confirmAsync) {
bootbox.confirmAsync = function (challenge, noGoMessage) {
challenge = challenge || 'Are you sure?';
noGoMessage = noGoMessage || 'User declined';
return jQuery.Deferred(function (def) {
bootbox.confirm(challenge, function (confirmed) {
confirmed ? def.resolve() : def.reject(new Error(noGoMessage));
});
}).promise();
}
}
doTheDeed()
将包含一个以bootbox.confirmAsync(...)
开头的完全传统的链,例如:
function doTheDeed () {
return bootbox.confirmAsync('Are you sure you want to delete?', 'User declined to delete')
.then(function (data) {
return $.post('/api/delete/123');
})
.then(null, function (err) {
// if user declined, then 'User declined to delete' will come back as err.message
console.log(err.message);
return err; // jQuery v<3.0
// throw err; // jQuery v>=3.0
});
}