【问题标题】:Problems with deferred object延迟对象的问题
【发布时间】:2012-09-11 08:22:31
【问题描述】:

我有一个问题,我试图通过在 javascript 中使用延迟对象来解决(而且我是延迟对象的新手)。

问题: 用户尝试运行一个函数(可以是很多不同的函数)。如果功能失败...它将尝试再次登录,然后再试一次(一次)。如果登录失败。那么一切都失败了。

这些函数和登录函数包含将返回的 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
});

【问题讨论】:

    标签: jquery ajax deferred


    【解决方案1】:

    所以基本上,您希望按顺序执行 3 个 deferred,并在第一次成功后停止。 我会使用像这样的通用函数:

    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(函数(){ // 你的第一次登录尝试 返回 $.ajax(...); }, 功能() { // 你的第二次登录尝试 返回 $.ajax(...); }, 功能() { // 您的最后一次登录尝试 返回 $.ajax(...); }).then(function() { /* 成功!*/ }, function() { /* 失败 */ });

    编辑: 好吧,我想我误解了这个问题。 这段代码呢:

    函数获取数据(){ 返回 $.ajax(...); } 功能登录用户(){ 返回 $.ajax(...); } var deferred = jQuery.Deferred(); 获取数据()。然后(函数(){ // 成功 deferred.resolve(); }, 功能() { loginUser().then(function() { 获取数据()。完成(函数(){ deferred.resolve(); }); }, 功能() { deferred.reject(); }); }

    【讨论】:

    • “所以基本上,你想按顺序执行 3 个 deferred,并在第一次成功后停止”。这取决于。逻辑是对运行 Ajax 函数并返回的通用函数进行函数调用(在本例中为 getData()。如果可行。一切都应该结束。如果失败,它将尝试调用 loginUser() 函数(这将尝试登录用户)。如果该函数失败......所有失败。如果它有效。第一个尝试但失败的函数(在这种情况下为 getData())将再次运行。如果再次失败。 ..都失败了。如果它有效...那么一切都很好。
    • 感谢您的回答和抽出时间。您在我的原始帖子中编写的代码几乎与我完全相同。只有我将它放在一个函数中并使用 window[func]() 才能调用任何函数(返回要处理的 ajax 延迟对象)。但这提出了一个问题。我可以依赖 dfd 在延迟的主代码完成后返回...查看我为提出问题而制作的简化函数:stackoverflow.com/questions/12386728/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多