Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide destroy/teardown method #1

Open
janstadt opened this issue Apr 1, 2015 · 1 comment
Open

Provide destroy/teardown method #1

janstadt opened this issue Apr 1, 2015 · 1 comment

Comments

@janstadt
Copy link

janstadt commented Apr 1, 2015

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

Drosty pushed a commit to Drosty/talker.js that referenced this issue Sep 8, 2015
@Jayiitb
Copy link

Jayiitb commented Feb 27, 2018

@janstadt Thanks for the thought. I am also facing timeout issue.
When do you call destroy? What if someone calls SendAsync multiple times? Then, I guess we'll not be able to destroy individual calls, as you are not keeping rejectTimeout for each calls.. it will be overridden by the next one...if otherwise the promise is not resolved or rejected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants