当前位置: 首页 > 知识库问答 >
问题:

Aurelia-在路由器预发送步骤中等待promise返回

尤飞尘
2023-03-14

tl;dr-我如何延迟aurelia-router.js中的processResult()函数的执行,因为我仍然在等待代码中的承诺的结果?它会导致正确的模块呈现,但地址不正确/href。

html" target="_blank">示例:如果您在base-module,然后单击admin,admin模块将加载,但href仍然是www.mycompany.com/#/base-module而不是www.mycompany.com/#/admin,并且可以在控制台中看到此错误:

错误[app-router]错误:预期路由器管道返回导航结果,但得到的是[{}]

较长版本:

我的路由器中有一个预置步骤,在呈现视图之前检查用户是否启用了特定模块。

在我的PreRenderStep类中,我有一个run函数,它调用一个中介来获取用户的权限,然后检查用户单击的模块是否在他们的enabled modules列表中。对调解人的呼吁涉及一个承诺。

问题是prerender步骤中的run承诺会在run方法中的承诺完成之前解决。因此,视图最终会呈现(因为启用了用户),但前面的href仍保留在地址栏中。

路由器:

null

 configureRouter(config, router) {
        config.title = "Tramonex";
        config.addPipelineStep('authorize', AuthorizeStep);
        config.addPreRenderStep(PreRenderStep);
        config.map([
            {
                route: ['', 'log-in-out'],
                name: 'home',
                moduleId: 'modules/authentication/log-in-out'
            },
            {
                route: 'passwordReset',
                moduleId: 'modules/authentication/password-reset',
            },
            {route: 'app', moduleId: 'app', auth: true},
            {
                route: 'base-module',
                name: 'base-module',
                moduleId: 'modules/base-module',
                href: 'base-module',
                nav: true,
                auth: true
            },
            {
                route: 'test1',
                name: 'test1',
                moduleId: 'modules/test1/test1',
                href: 'test1',
                nav: true,
                auth: true,
                settings: {moduleAuthRequired: true}

            },
            {
                route: 'test2',
                name: 'test2',
                moduleId: 'modules/test2/test2',
                href: 'test2',
                nav: true,
                auth: true,
                settings: {moduleAuthRequired: true}
            },
            {
                route: 'admin',
                name: 'admin',
                moduleId: 'modules/admin/admin',
                href: 'admin',
                nav: true,
                auth: true,
                settings: {moduleAuthRequired: true}
            },
        ]);

        this.router = router;
    }
}

null

PreRenderStep:

null

@inject(Mediator, AuthenticationService)
class PreRenderStep {

    constructor(mediator, authenticationService) {
        this.mediator = mediator;
        this.authenticationService = authenticationService;
    }

    run(navigationInstruction, next) {
       
        if (navigationInstruction.getAllInstructions().some(i => i.config.settings.moduleAuthRequired)) {

            this.redirect = false;
            this.mediator.getPermissionsForUser()
                .then(user => {
                    userPerms = user.modules;
                    var isEnabled = userPerms.includes(navigationInstruction.config.name);
                    if (!isEnabled) {
                        this.redirect = true;
                    }
                })
                .then(() => {
                    return this.redirect next.cancel(navigationInstruction.router.navigateToRoute('base-module')) : next();
                });
        }
        else {
            return next();
        }
    }
}

null

当用户单击一个需要验证检查的模块时,就会命中代码,而当我们等待Mediator.getPermissionsForUser()的承诺返回时,就会命中aurelia-router.js中的代码(带星号的行):

null

function processResult(instruction, result, instructionCount, router) {
  if (!(result && 'completed' in result && 'output' in result)) {
    result = result || {};
    **result.output = new Error('Expected router pipeline to return a navigation result, but got [' + JSON.stringify(result) + '] instead.');**
  }

  var finalResult = null;
  if (isNavigationCommand(result.output)) {
    result.output.navigate(router);
  } else {
    finalResult = result;

    if (!result.completed) {
      if (result.output instanceof Error) {
        logger.error(result.output);
      }

      **restorePreviousLocation(router);**
    }
  }

null

共有1个答案

万俟小林
2023-03-14

您需要返回在run函数中创建的承诺。

return this.mediator.getPermissionsForUser()
 类似资料:
  • 我试图理解为什么这段代码返回“Promise{pending}”。 当我通过reduceDirections()函数时,我可以看到我得到了想要的结果。但是当我(一行之后)时,我会改为“Promise pending” 很抱歉,我不理解promise和异步等待。我曾尝试在mdn上阅读和观看视频,但我不知道如何将它们显示的内容转移到这个问题上。提前感谢您的帮助!

  • MDN文档 异步/等待函数的目的是简化同步使用promise的行为,并对一组promise执行某些行为。正如promise类似于结构化回调一样,async/await类似于组合生成器和promise。 我了解异步/等待、生成器和promise的基本概念。然而,我不完全理解说async/await类似于将生成器和promise结合起来意味着什么。 所以async/wait简化了生成器和promise

  • 我有一个包含100个promise的promise数组。我想等待,直到一个promise以真实的价值实现。另外,我想确保只有x个promise同时运行(设置限制)。 我已经研究了像和这样的方法,但是它们没有并发选项。 我该怎么做呢?

  • 我试图利用es7异步功能,即。 在这里,所有promise*函数都进行ajax调用,并返回或如果ajax响应满足传递的参数,我相信我不能连续使用3个等待,因此需要一种方法来等待所有这些调用以某种方式返回它们的值。

  • 我正在使用节点8.x。因此,我可以访问所有最新的特性,如异步/等待等。 该场景类似于以下内容(语法不正确,仅供解释): 基本上,User对象的创建依赖于address对象的创建。我希望createUser函数异步执行,即尽快返回一个promise而不等待address对象的创建。 这个问题的目的不是完成任务,而是了解在异步编程中解决这类问题的最佳方法是什么。 我能想到的方法不多:1:创建一个新的p

  • 我用webpack建立了一个浏览器umd库。 我正在侦听输入文件的onchange事件。当有人提交图像/文件时,它会将其转换为base64。我试图让它尽可能看起来不那么明显,所以我使用了promises和wait/asynchttps://blog.shovonhasan.com/using-promises-with-filereader/. 但是,有一个问题-当我调用convertToBase