Return 在 deferred.done 中,不 returns 来自函数

Return in deferred.done ,does not returns from the function

我正在使用 Deferred.Done 方法,它再次被另一个 jquery 函数调用,

但即使是点 (a) {return false},它仍然会到达点 (b),

我在这里做什么?..

  function InitialMethod(isInitialCallToMethod) {

//Call using deferred method
CheckUserSession()
    .done(function (isSessionAvailable) {

        //Session data exists for end user.
        if (!isSessionAvailable) {
            //reopen modal to get user details
            OpenUserSessionModal();
            return false; --(a)
        }
    })
    .fail(function (error) {

         //reopen modal to get user details
         OpenUserSessionModal();

         //open failure div to notify user
         OpenJqueryPopup('#divDialogFailure');
         return false;
});

//Is method called for the first time,after document load?
if (isInitialCallToMethod) {

    //bind elearning tabs
    CreateElearningTabs();
}
return true; ---(b)
}

您不能简单地从回调函数 return 并期望原始作用域像它自己的那样尊重 return 语句。您可以 return 函数中的另一个承诺,如下所示:

function InitialMethod(isInitialCallToMethod) {

  // your main function's result
  var result = jQuery.Deferred();

  //Call using deferred method
  CheckUserSession()
      .done(function (isSessionAvailable) {

          //Session data exists for end user.
          if (!isSessionAvailable) {
              //reopen modal to get user details
              OpenUserSessionModal();
              // resolve to false
              result.resolve( false );
          }

          //Is method called for the first time,after document load?
          if (isInitialCallToMethod) {
              //bind elearning tabs
              CreateElearningTabs();
          }
          // resolve to true
          result.resolve( true );
      })
      .fail(function (error) {

           //reopen modal to get user details
           OpenUserSessionModal();

           //open failure div to notify user
           OpenJqueryPopup('#divDialogFailure');

           // resolve to false
           result.resolve( false );
  });

  // return a new promise
  return result.promise(); 
}

或者更紧凑一点

function InitialMethod(isInitialCallToMethod) {

  //Call using deferred method
  return CheckUserSession()
      .then(function (isSessionAvailable) {

          //Session data exists for end user.
          if (!isSessionAvailable) {
              //reopen modal to get user details
              OpenUserSessionModal();

              // resolve to false
              return false;
          }
          return true;
      }, function (error) {

           //reopen modal to get user details
           OpenUserSessionModal();

           //open failure div to notify user
           OpenJqueryPopup('#divDialogFailure');

           // resolve to false
           return false;

      })
      .then( function( ok ){
        if (ok && isInitialCallToMethod) {
            //bind elearning tabs
            CreateElearningTabs();
        }
        return ok;
      });
}

请注意,在这两种情况下,结果都是不是布尔值,而是一个承诺!

三件事要明白:

  • 代码中的两个 return false 语句都 return 来自它们各自的 .done().fail() 处理程序,而不是来自外部函数。
  • 从 jQuery 的 .done().fail() 返回任何内容都是没有意义的。无论 returned 是什么,这两种方法都保证不改变地传递它们的输入承诺。只有 jQuery 的 .then() 有权 "filter" - 即传递新的承诺。
  • 将 jQuery 承诺链从成功路径转移到错误路径的唯一方法是 return 拒绝承诺。返回 false,即使来自 .then() 处理程序也不会有相同的效果。

我猜你只想在 isSessionAvailable 为真且 isInitialCallToMethod 为真时调用 CreateElearningTabs(),在这种情况下:

function InitialMethod(isInitialCallToMethod) {
    return CheckUserSession().then(function (isSessionAvailable) {
        if (isSessionAvailable) {
            if (isInitialCallToMethod) {
                CreateElearningTabs();
            }
        } else {
            OpenUserSessionModal();
            return $.Deferred().reject(new Error('session not available')).promise();
        }
    }, function (error) {
        OpenUserSessionModal();
        OpenJqueryPopup('#divDialogFailure');
        return error;
    );
}

您可以设法避免重复语句 OpenUserSessionModal()(例如,错误处理程序可以测试 error),但这不是什么大问题。

通过returnInitialMethod()的承诺,调用者可以获得结果。