首先,我承认,掌握延迟管道 API 是最近对我来说最具挑战性的事情。
要求
如果一系列检查通过,我想提交一份表格。
其中一些是具有同步客户端验证的函数,一些是执行 AJAX 调用的异步检查。异步函数返回 bool 回调值。
同步和异步函数都可能有
confirm()
提示来接受用户输入。用户输入将决定是否执行下一个 block (如果用户选择取消确认对话框,则下一个 block 不应继续),因此不应提交表单。 这非常重要。只有当所有单独的 block 都返回(或回调)true 时,才应提交表单。
稍后添加 - 异步函数可能在某些条件下包含ajax调用,因此在某些用例中,ajax调用可能无法完成。
- 在异步函数内,AJAX 响应处理代码内可能存在用户确认检查。
以下是我的函数结构 -
function synchronousMethod()
{
//some logic
return (confirm("user input"));
}
function aSynchronousMethod1(callback)
{
if(condition)
{
//ajax call
callback(bool); //does callback true/false
}
else
{//some use cases may follow this path and not make the AJAX call at all.
return true;
}
}
以下是我对 $.Deferred 的尝试之一(可能我做的完全错误)-
$.when( synchronousMethod(), aSynchronousMethod1(),aSynchronousMethod2())
.done(function() {
//I want to submit my form if all the functions returned/called-back true
console.log("submitting form");
})
.fail(function() {
console.log( 'I fire if one or more requests failed.' );
});
但是文本“提交表单”在异步函数完成之前执行,并且异步函数也会导致此错误TypeError:回调不是函数
。
我观察到,如果我不在 $.when
内的函数调用后面放置括号,即如果我保持这样 -
$.when(synchronousMethod, aSynchronousMethod1,aSynchronousMethod2)
但没有任何函数执行。
更新
另一种方法
我也尝试过类似的方法,但遇到了与第一种方法类似的问题 -
var promise = defer.pipe(synchronousMethod);
promise = promise.pipe(aSynchronousMethod1);
promise = promise.pipe(aSynchronousMethod2);
promise = promise.pipe($("form#frmCampaigns").submit());
更新2 添加了两点 -
异步函数可能在某些条件下包含ajax调用,因此在某些用例中,ajax调用可能无法完成。
在异步函数中,AJAX 响应处理代码中可能存在用户确认检查。
更新了异步函数的结构 -
function aSynchronousMethod1(callback)
{
//some sync logic here
if(condition) /*some condition*/
{
//ajax call
if(ajax sucess response)
{
callback((confirm("If user accepts"));
}
else
{
callback(false);
}
}
else
{//some use cases may follow this path and not make the AJAX call at all.
callback(true);
}
}
最佳答案
我不确定我是否完全理解你的例子。但我认为问题可能是,你的异步方法应该返回一个 Promise (就像 $.ajax 的返回值):
function sync() {
return "something";
}
function async1() {
return $.ajax("http://www.foo.com");
}
function async2() {
return $.ajax("http://www.bar.com");
}
$.when(sync(), async1(), async2()).done(function() {
console.log("success");
}).fail(function() {
console.log("error");
});
这是一个工作示例:http://jsfiddle.net/CcsQz/
更新
好的,我明白了。也许你可以根据你的情况做这样的事情:
function syncOrAsync(sync, confirm) {
var deferred = jQuery.Deferred()
if (sync) {
deferred.resolve();
} else {
$.ajax('http://www.foo.com').done(function(data) {
if (confirm(data)) {
deferred.resolve();
} else {
deferred.reject();
}
}).fail(function() {
deferred.reject();
});
}
return deferred.promise();
}
var confirm = function(data) {
// check confirmation here
return true;
}
var method1 = syncOrAsync(true, confirm);
var method2 = syncOrAsync(false, confirm);
$.when(method1, method2).done(function() {
console.log('done');
}).fail(function() {
console.log('fail');
});
更新的 fiddle :http://jsfiddle.net/mKdwN/
关于jquery - 仅当一系列流程通过时才使用 jQuery 延迟提交表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16734698/