如何使用确认警报并返回AJAX承诺?

我有一个返回AJAX承诺的现有函数。 我想更新此函数以在运行AJAX调用之前显示确认警报,但代码的其他部分使用此函数并且已经期待一个承诺。

这是我原来的function:

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*/ }); 

我是否需要根据用户的回复有条件地返回不同的承诺?

你可以使用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 }); 

基于Adeneo的回答,并坚持最低级别的promisifying原则,bootbox可以通过bootbox.confirm()的可重用的promisification来进行bootbox.confirm() ,而不必破解bootbox本身。

如果你这样做,那将是合适的:

  • 允许调用者指定质询文本和noGo消息。
  • 向错误路径发送noGo条件。
 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 }); }