在 resolve 中使用 socket.io 实现一次性监听器

Use socket.io in resolve to realise one-time listeners

我曾经把一次性听众放在 resolve 里面。下面的代码可以确保页面必须接收消息yes来解析x,然后"yes again"来解析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 来实现事件监听器的作用?

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

可以创建某种界面,您可以在其中获得一系列承诺,第一个承诺由第一个事件触发器解决,第二个承诺由第二个事件触发器解决,依此类推,但您必须调用一个函数来获得下一个承诺,以便有一些代码可以做出新的承诺,并有一个调用者 return 它(这可能最终会让人感觉像是一个 hack 使用)。为每个事件触发器使用常规回调可能更简单,如果您随后想要基于事件触发器执行一些进一步的异步操作,您可以在此时创建一​​个承诺来帮助您管理进一步的活动。

Promise 只是不适合重复发生的事件的架构匹配。Promise 是一次性设备,因此它们应该用于表示一次性事件。打开一个文件,当该文件现在打开时得到一个解决的承诺。发出一个特定的 http 请求并获得一个通过请求的响应解决的承诺。

我使用下面的代码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