延迟对象的问题
我有一个问题,我试图通过在javascript中使用延迟对象来解决(我是新的延迟对象)。
问题:用户尝试运行一个函数(可能有很多不同的函数)。 如果函数失败…它将尝试再次登录然后再试一次(一次)。 如果登录失败。 那么一切都失败了。
这些函数和login函数包含将返回的Ajax调用。
我的问题是:在函数中的所有其他代码运行之后,我可以依赖于var dfd(在tryAjax函数的末尾)最后执行吗?
这是代码:
function tryAjax(func) { var dfd = new jQuery.Deferred(); window[func]().then( function(p1,p2,p3) { //Everything worked great. No need to login. dfd.resolve(p1,p2,p3); }, function() { //func failed //try to login user again before trying. loginUser().then( function() { //Login success //Try to run func again. window[func]().then( function(p1,p2,p3) { //Func succes after login dfd.resolve(p1,p2,p3); }, function(p1,p2,p3) { //Func failed after login dfd.reject(p1,p2,p3); }); }, function(p1,p2,p3) { //Login failed dfd.reject(p1,p2,p3); }); }); return dfd; } And to call it: tryAjax('getData').then( function(p1,p2,p3) { //Success }, function(p1,p2,p3) { //Error });
所以基本上,你想按顺序执行3个延迟,并在第一次成功后停止。 我会使用像这样的通用函数:
function dfdSequence() { var deferred = jQuery.Deferred(); var execute = function(functions) { var promise = functions[0].apply(functions[0], args); promise.done(function() { deferred.resolve(); }); if (functions.length === 1) { // It was the last call promise.fail(function() { deferred.reject(); }); } else { // Fail, let's move on the next function promise.fail(function() { execute(functions.slice(1, functions.length)); }); } }; execute(Array.prototype.slice.call(arguments, 0, arguments.length)); return deferred.promise(); }
该函数接受任意数量的函数并按顺序执行。 基本上,每个函数都返回一个promise,如果promise被拒绝,则执行下一个函数。 使用范例:
dfdSequence(function(){ //首次登录尝试 return $ .ajax(...); },function(){ //第二次登录尝试 return $ .ajax(...); },function(){ //您上次登录尝试 return $ .ajax(...); })。then(function(){/ * Success!* /},function(){/ * Failure * /});
编辑:嗯,我想我误解了这个问题。 这段代码怎么样:
function getData(){ return $ .ajax(...); } function loginUser(){ return $ .ajax(...); } var deferred = jQuery.Deferred(); getData()。then(function(){ //成功 deferred.resolve(); },function(){ loginUser()。then(function(){ getData()。done(function(){ deferred.resolve(); }); },function(){ deferred.reject(); }); }