在deferred.done中返回,不从函数返回

时间:2015-08-03 12:03:08

标签: javascript jquery jquery-deferred

我正在使用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)
}

2 个答案:

答案 0 :(得分:3)

您不能简单地从回调函数返回并期望原始范围尊重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;
      });
}

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

答案 1 :(得分:3)

要理解的三件事:

  • 代码中的两个return false语句都从各自的.done().fail()处理程序返回,而不是从外部函数返回。
  • 从jQuery的.done().fail()返回任何内容都是毫无意义的。无论返回什么,两种方法都保证不会传递其输入保证。只有jQuery的.then()才有能力“过滤” - 即传递新的承诺。
  • 将jQuery promise链从其成功路径转移到错误路径的唯一方法是返回被拒绝的promise。即使从false处理程序返回.then()也不会产生相同的效果。

我猜你只是在CreateElearningTabs()真实而且isSessionAvailable真实的情况下才打电话给isInitialCallToMethod,在这种情况下:

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),但这不是一个大问题。

通过从InitialMethod()返回一个承诺,结果可供调用者使用。