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

在Angular[重复]中使用异步服务的同步服务

武峻熙
2023-03-14

我有一个链接生成器服务,它能够生成到特定内容类型的链接(用户的详细信息页面,内容项目的详细信息页面等)。

这个服务真的很好用,而且有同步功能:

links.content(contentInstance); // /items/123
links.user(userInstance); // /users/234

现在,我必须为登录用户引入单独的路由,以便将/users/id更改为/users/me

我需要添加到链接生成器服务中的唯一更改是检查userinstance.id==loggedinuser.id并返回不同的路由URL。这不是一个问题,只要我的登录用户的信息将是同步可用的。但这不是...

我有一个userService.getMyInfo()返回一个承诺。第一次调用它时,它实际上发出了一个服务器请求,但随后的调用返回一个已解析的承诺,其中包含已缓存的数据。

那么我应该如何在我的链接生成器服务中实现我的用户链接URL生成呢?

好的。为了更好地了解我目前的情况,以及我的问题出在哪里。我很清楚异步将保持异步,并且它不能被转换为同步(也不应该如此)。

这是我的一些代码,这将使它更容易理解。

angular
    .module("App.Globals")
    .factory("linkGenerator", function(userService) {
        ...
        user: function(userInstance) {
            // I should be calling userService.getMyInfo() here
            return "/users/{0}/{1}".format(userInstance.id, userInstance.name);
        },
        ...
    });
angular
    .module("App.Globals")
    .service("userService", function($q, cacheService, userResource) {
        ...
        getMyInfo: function() {
            if (cacheService.exists("USER_KEY"))
                // return resolved promise
                return $q.when(cacheService.get("USER_KEY"));

            // get data
            return userResource
                .getCurrentUser()
                .$promise
                .then(function(userData) {
                    // cache it
                    cacheService.set("USER_KEY", userData);
                });
        },
        ...
    });
angular
    .module("App.Content")
    .controller("ItemDetailsController", function(linkGenerator, ...) {
        ...
        this.model = { ... };
        this.helpers = {
            ...
            links: linkGenerator,
            ...
        };
        ...
    });

视图使用ItemDetailsController作为上下文表示法。

...
<a ng-href="{{::context.helpers.links(item.author)}}"
   ng-bind="::item.author.name">
</a>
...

如您所见,我的视图生成到项作者的链接。问题是,我的LinkGenerator(如您从代码中所看到的)可能还没有信息,它是否应该生成到用户详细信息视图的正确链接之一。

我知道我不能(也不想)将我的异步代码更改为同步的,但是什么才是使这个东西按预期工作的最佳方法呢?

目前我已经想出了一个解决方案,但我并不喜欢它,因为我必须向LinkGenerator.user(userInstance,loggedInUserId)函数提供登录用户的ID。然后设置路由,以便将resolve添加到路由中,在路由中调用userService.getMyInfo(),这意味着在解决所有承诺之前,不会实例化我的控制器。沿着这条线:

routeProvider
    .when("...", {
        templateUrl: "path/to/my/details/template",
        controller: "ItemDetailsController".
        controllerAs: "context",
        resolve: {
            myInfo: function(userService) {
                return userService.getMyInfo();
            }
        }
    })
    ...

然后我还向我的控制器添加了一个额外的助手

this.helpers = {
    ...
    links: linkGenerator,
    me: myInfo.id,
    ...
};

然后我还通过添加我在视图中提供的附加参数来更改链接生成器的功能。

linkGenerator.user = function(userInstance, loggedInUserId) {
    if (userInstance.id === loggedInUserId)
        return "users/me";
    return "users/{0}/{1}".format(userInstance.id, userInstance.name);
}

在视图中

<a ng-href="{{::context.helpers.links.user(item.author, context.helpers.me)}}"...

而且我并不总是提供登录用户的ID。我想让我的服务自行处理这些数据。

共有1个答案

沈栋
2023-03-14

没有办法使JavaScript中的任何东西在某一点上是异步的再次同步。这是并发如何工作的基本规则--不允许阻塞等待东西。

相反,您可以让您的新方法返回一个承诺,并使用常规工具等待它的解决。

links.me = function(){
     var info = userService.getMyInfo();
     return info.then(info => { // or function(info){ if old browser
          // generate link here
          return `/users/${info.id}`; // or regular string concat if old browser
     });
}

您必须将其异步使用为:

links.me().then(function(link){
    // use link here
});
 类似资料:
  • 我是web服务开发的初学者。我们正在使用Spring3用java构建RESTWeb应用程序。 我们正在使用的Web服务具有异步登录方法。我们为他们提供了一个回调监听器URL,他们的服务在其中发回响应。 因此,当我们发送登录请求时,我们会收到一个空白响应作为确认。和服务发送一个响应,其中包含侦听器URL上的实际数据。 请帮助,我应该如何设计/实现调用登录服务作为同步调用?谢谢 编辑:下面是回发消息的

  • 异步Tcp客户端 异步Http客户端 异步Redis客户端 异步Mysql客户端 异步Log日志 异步文件读写 异常Exception

  • 我可能遗漏了一些非常明显的东西,但我想做的是在组件之间异步共享从服务器获取的数据。 我的服务看起来是这样的: 因为流程是异步的,所以我需要promise响应,但是promise的响应返回实际的subscribe对象,而不是返回的< code>data.json。 这是一个配置文件页面,它由嵌套路由组成,所以我不能将数据传递给路由组件。路由组件之一是帖子,加载配置文件后,它应该开始获取服务中当前用户

  • 异步Log日志 use AsyncLog; yield AsyncLog::info('hello world'); yield AsyncLog::debug('test debug', ['foo' => 'bar']); yield AsyncLog::notice('hello world',[], 'group.com'); yield Async

  • 我理解同步服务器和异步服务器之间的区别,但是我想知道,如果有这两种情况,哪一种更适合异步服务器还是同步服务器? > 同步:写入调用将被阻塞,直到消息准备好从内部完成队列通过线路发送。异步:写入调用立即返回,我们需要等待完成队列。在同步服务器中,如果我们添加队列,该队列基本上为evry写入调用和其他线程填充,并将其耗尽并执行stream.write然后性能将相同? 同步:gRPC内部创建线程池,线程

  • 或者我可以使用一对服务器/客户端来处理同步请求,另一对来处理异步请求吗?我刚刚开始研究一个实现gRPC的分布式项目。我应该有多个数据库节点,每个都应该能够发送RPC到另一个。我必须同时允许同步和异步RPC。一个用于一般请求,另一个用于两阶段提交。但是gRPC教程没有提到我是否应该将两个服务合并到一台服务器中,并将它们分开。谢谢