在之前的`then`

时间:2016-09-07 14:04:56

标签: javascript jquery ajax promise

我正在重构一个大型JS类(它严重依赖于jQuery),并将回调,变量和紧密交织的代码混乱转换为一系列执行所需更改的promise链,每个由触发事件的不同用户操作触发。

该脚本用于HTML游戏链接页面上的模态。我遇到问题的部分确实按顺序执行:

  1. 收听游戏'按钮被按下。
  2. 从按钮的数据属性中提取有关游戏的信息。
  3. 打开带有加载动画的模态。
  4. 有条件地使用其中一些信息从该服务的API获取正确的用户令牌。
  5. 有条件地使用其中一些信息POST到另一个API,以获取为游戏本身提供服务的服务。响应对象包含游戏本身的URL。
  6. 用该网址替换iframe src属性,关闭加载动画,并显示iframe。
  7. 所有相关信息 - 网址,代码,令牌,标题等 - 都保存在名为state的对象中。 promises链中使用的每个函数都将此状态对象作为其唯一参数,并返回修改后的版本。通常,它会产生单一的副作用(通常是DOM更新)。更新必须按顺序进行,目前我在调试时将每个离散动作拆分为一个单独的函数(updateState函数实际上是Object.assign +一些日志记录):

    function gameSetupHandler(e, state) {
      const eventData = rejectEmptyProps($(e.target).data());
      const isDemo = $(e.target).hasClass(state.demoTriggerClass);
      Promise.resolve(resetState(state))
             .then(getPlayerTokenAndId) // AJAX request 1 (#4 in above list)
             .then(disableGameLoadButtons)
             .then(state => updateState(state, eventData, { isDemo }))
             .then(setModalGameState)
             .then(calculateAspectRatio)
             .then(calculateModalSize)
             .then(setupResizeHandler)
             .then(showModal)
             .then(getLaunchUrl) // AJAX request 2 (#5 in above list)
             .then(setGameSrc)
             .then(showGame)
             .catch(error => console.log(error.message));
    }
    

    一个简单函数的例子:

    function disableGameLoadButtons(state) {   $(state.loadGame).attr('disabled', true);   return state; }
    

    我在第二个AJAX请求中遇到问题。所以第一个AJAX请求如下所示:

    function getPlayerTokenAndId(state) {
      return Promise.resolve($.get('/api/Lobby/PlayerToken')
                              .done(response => {                             return updateState(state, { playerToken: response.GameToken, playerId: response.UserId });
                              })
                              .fail(() => alert(state.errorMsgToken)));
    }
    

    工作正常:链接继续,状态更新,模式出现在屏幕上。

    但第二个请求更复杂,有条件:

    function getLaunchUrl(state) {
      const player = {
        PlayerId: (state.isDemo) ? 0 : state.playerId,
        PlayerToken: (state.isDemo) ? 'demotoken' : state.playerToken,
        Currency: 'GBP',
        Channel: 'desktop',
        Language: 'EN',
        AutoLaunch: false,
        IsDemo: state.isDemo,
        SourceUrl: '',
        SourceArea: '',
        TableId: state.tableId,
        Technology: state.technology,
      };
    
      if (state.url !== 'gms') {
        const url = state.url.replace('{PLAYER_TOKEN}', state.playerToken).replace('{PLAYER_ID}', state.playerId);
        return updateState(state, { url: url });
      }
    
      return Promise.resolve($.ajax({
                      url: `/gamelaunch/v1/games/${state.softwareId}/launch`,
                      type: 'post',
                      contentType: 'application/json',
                      data: JSON.stringify(player),
                      headers: {
                        'X-Correlation-Token': uuid.v4(),
                        'X-Site-Code': state.siteCode,
                        'X-CSRF-Token': state.csrfToken
                      }
                    })
                    .done(response => updateState(state, { url: response.launchUrl }))
                    .fail(() => {
                      gameCloseHandler(null, state);
                      alert(state.errorMsg);
                    }));
    }
    

    以下是链接:

    function setGameSrc(state) {
      $(state.gameIframe).attr('src', state.url);
      return state;
    }
    

    我可以查看正在更新的状态 - 这很好。当我检查控制台日志记录时,gameModal.state中的游戏URL没问题。但是那时setGameSrc函数似乎永远不会触发,并且游戏src永远不会添加到DOM中,并且游戏永远不会显示。我也没有抓到任何错误。我可能会在这里错过一些愚蠢的东西,但我一直在来回走动,而且无法看到我未能做到的事情。

    如果有人请求

    ,我会发布更多代码

0 个答案:

没有答案