使用socket.io来解决实现一次性监听器的问题

时间:2017-06-27 21:13:48

标签: javascript socket.io promise angular-ui-router q

我曾经把一次性听众放在resolve里面。以下代码可确保页面必须收到消息yes才能解析x,然后再次"是"解决y等问题:

app.config(['$stateProvider', function ($stateProvider) {
    $stateProvider
        .state('edit', {
            resolve: {
                x: ['$q', function ($q) {
                    var deferred = $q.defer();
                    $window.addEventListener("message", function (e) {
                        if (e.data === "yes") deferred.resolve(e.data)
                    }, { once: true };
                    return deferred.promise
                }],
                y: ... ...
                        if (e.data === "yes again") deferred.resolve(e.data)
                   ... ...
                    return deferred.promise
                }],
                z: ... ...
                    return deferred.promise

现在我想用socket.io来实现听众;它侦听服务器发出的消息。如果它不在resolve中,我会使用以下内容来接收消息:

var socket = io.connect();
socket.on('message', function (message) {
   console.log(message)
})

我需要为一个页面获得一个socket。有谁知道如何将它放入几个resolve来实现事件监听器的功能?

2 个答案:

答案 0 :(得分:1)

事件监听器与promises不一致,因为promises是一次性设备,但事件监听器可以多次调用。因此,如果您为事件创建承诺,它将只被调用一次,并且将忽略在第一个事件之后发生的任何事件。

有可能创建某种接口,你得到一系列的承诺,第一个使用第一个事件触发器解决,第二个承诺使用第二个承诺,依此类推,但是你必须调用一个函数获得下一个承诺,以便有一些代码,使新的承诺,并有一个调用者返回它(这可能最终感觉像一个黑客使用)。对每个事件触发器使用常规回调可能更简单,如果您希望基于事件触发器执行一些进一步的异步操作,那么您可以在此时创建一​​个承诺来帮助您管理进一步的活动。

Promise对于重复发生的事件来说不是一个合适的架构匹配。 Promise是一次性设备,因此它们应该被用来代表一次性事件。打开一个文件,获得一个在该文件现在打开时解析的回复。发出一个特定的http请求并获得一个可以根据请求的响应解决的承诺。

答案 1 :(得分:0)

我使用以下代码socket.once模仿一次性监听器,到目前为止它没有错误地工作:

app.config(['$stateProvider', function ($stateProvider) {
    $stateProvider
        .state('edit', {
            resolve: {
                socket: [function () {
                    return io.connect();
                }],
                x: ['socket', '$q', function (socket, $q) {
                    var deferred = $q.defer();
                    socket.once("message", function (msg) {
                        if (msg.req === "yes") deferred.resolve(msg)
                    })
                    return deferred.promise
                }],
                y: ... ...
                        if (msg.req === "yes again") deferred.resolve(msg)
                   ... ...
                    return deferred.promise
                }],
                z: ... ...
                    return deferred.promise