Skip to content

Provide destroy/teardown method #1

Description

@janstadt

We're using talker.js in an angular SPA that loads an iframe after clicking on an item from a list. Upon click, we launch an iframe containing an application that is required to setup a talker instance to communicate with the parent. The parent app controls when the iframe is present, but when we navigate away from the iframe, the window and event listeners are still present via window["frameName"]. If we navigate away from the iframe while waiting for a message to be responded to, the Talker instance gets nulled out BUT the event listener is still alive so the _receiveMessage method still gets called and throws an exception.

Talker.prototype.destroy = function () {
    if (this.rejectTimeout) {//see below on this
        clearTimeout(this.rejectTimeout);
    }
    if (this._listener) {
        window.removeEventListener("message", this._listener, false);
        this._listener = null;
    }
};

We also have a number of scenarios that are fire and forget type of messages where the outer iframe just tells the inner one something and does not require a response. It would be nice to have a send and sendAsyc method where the sendAsync method creates the promise and requires a response and send just sends the message without creating the promise. The issue happens when we send a message without expecting a response so the promise in the setTimeout gets rejected after the timeout expires. Apart from setting our timeout to something astronomical, we end up with a lot of rejected promises with the timeout message. Would you consider doing something like this:

Talker.prototype.sendAsync = function(namespace, data, responseToId) {
    var message = new Talker.OutgoingMessage(this, namespace, data, responseToId);

    var promise = pinkySwearPromise();
    this._sent[message.id] = promise;

    this._queue.push(message);
    this._flushQueue();

    this.rejectTimeout = setTimeout(function() {
        promise(false, [new Error(TALKER_ERR_TIMEOUT)]); // Reject the promise
    }, this.timeout);

    return promise;
    };

Talker.prototype.send = function(namespace, data, responseToId) {
    var message = new Talker.OutgoingMessage(this, namespace, data, responseToId);
this._postMessage(message);
    };

and then in the destroy method we would clear the this.rejectTimeout timer. At the moment we are doing these things in our version of talker.js but it might be handy for others who could potentially run into this issue.

Thanks,

Jake

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions