我最近在jQuery中使用$ .Deferred()进行了一些测试并得到了一个问题。虽然deferred和promises非常适合只打算运行一次的ajaxcalls,但我还有一个用于添加新用户的表单,带有ajax的帖子需要多次运行。现在这与延迟/承诺的二进制(ish)状态崩溃,因为一旦它们被解决或被拒绝它将保持该状态。所以我的问题是:
- 我可以将deferred用于多次调用的任务吗? - 如果可能的话,是否建议使用deferred,或者我应该只使用$ .ajax的成功/错误回调来坚持旧方法?
这里有一些代码我一起发布了表单,这个代码很好用,但不是多次。
var submittingUser = new $.Deferred();
var savingUser = submittingUser.pipe(function(data) {
return $.post('ajax.php', data);
});
$("#add_new_user").click(function() {
var data = $("#add_user_form").serialize();
submittingUser.resolve(data);
return false;
});
savingUser.then(function() {
//Success
}, function() {
//Failed
});
答案 0 :(得分:2)
以这种方式使用延迟是没有意义的。延期代表一项行动;你不能将它用作事件发射器。您在启动异步操作时使用延迟,并希望在该操作成功或失败时执行某些操作。
$.post()
返回一个promise(实际上它返回一个jqXHR实例,然而它实现了promise接口),因此你可以$.post(...).fail(handleFailure).done(handleSuccess)
。但是,每当发生某些事情时,你都不能使用延迟来运行一些代码。
答案 1 :(得分:2)
延迟对象只是设计一次,即使之后也允许添加回调 延期已经解决并被解雇。
从你的代码来看,似乎不清楚为什么你不能只是:
$("#add_user_form").submit( function(e){
e.preventDefault();
$.post( "ajax.php", $(this).serialize() ).then( function(){
}, function() {
});
});
答案 2 :(得分:0)
我知道这是一个古老的主题,以前的答案是原始海报问题的完美解决方案,但我遇到了尝试多次解决延迟对象的相同问题,因此我想分享一个解决方案。 / p>
即使以下情况不可能:
var d = $.Deferred();
d.done(function(text){
alert('resolved ' + text);
});
d.resolve('Once'); // prints resolved once
d.resolve('Twice'); // this does nothing as done is only fired once
只需使用jQuery Deferred对象的progress / notify函数即可实现完全相同的效果。只是做:
var d = $.Deferred();
d.progress(function(text){
alert('resolved ' + text);
});
d.notify('Once'); // prints resolved once
d.notify('Twice'); // prints resolved twice
通过这种方式,您的延迟对象永远不会真正解决,但它可以让您根据需要启动任意数量的异步事件调用。也许这不是以这种方式解决问题的最佳软件设计,但我发现它对我刚才的情况很有用。