箭头函数中的WebSocket回调没有在词法上设置'this'

时间:2016-05-07 04:42:36

标签: websocket typescript angular

我正在尝试在Angular 2中创建一个WebSocket服务。这是我到目前为止所拥有的:

import {Injectable} from "angular2/core"
@Injectable()
export class ServerService {

    public ws:WebSocket;

    public myData = {};

    constructor() {
        let ws = new WebSocket('ws://localhost:8080/');

        ws.onopen = (event:Event) => {
            console.log("Socket has been opened!");
        };

        ws.onmessage = (event:Event) => {
            this.myData = JSON.parse(event.data);
        };
    };
}

问题是,当onmessage运行时,this关键字将成为WebSocket对象,而不是ServerService对象。

似乎我的箭头功能是一个标准功能。可能是什么导致了这个?还有另一种方法可以回到ServerService对象吗?

3 个答案:

答案 0 :(得分:4)

好的,所以在看到Abdulrahmans的例子在插上工作之后,我想我的环境可能有问题。结果我的TypeScript正在编译为ES5,并输出:

function ServerService() {
                var _this = this;
                this.myData = {};
                var ws = new WebSocket('ws://localhost:8080');
                ws.onopen = function (event) {
                    console.log("Socket has been opened!");
                };
                ws.onmessage = function (event) {
                    _this.myData = JSON.parse(event.data);
                };
            }

我的箭头功能确实被删除了,但是替换为应该(?)功能相同的东西。它在Firefox中按预期工作,但在Chrome中没有(我正在调试的地方)。

我将TypeScript编译器切换为输出ES6,现在我的JavaScript中有箭头功能,我的代码在两个浏览器中都按预期工作。

答案 1 :(得分:3)

我使用Function.prototype.bind()修复了它,它仅适用于oldschool匿名函数,而不是箭头函数。

所以而不是:

every 5.minutes do
  rake 'task_namespace:send_mail'
end

我做了:

ws.onmessage = (event:Event) => {
    this.myData = JSON.parse(event.data);
};

答案 2 :(得分:0)

我认为websocket在相应实例的上下文中执行回调(使用print zip(*df["0"]) [('a', 'x'), (1, 10)] call方法)。

解决方法包括将websocket事件处理程序包装到一个observable中:

apply

这样您就可以使用箭头功能和上下文:

initializeWebSocket(url) {
  this.wsObservable = Observable.create((observer) => {
    this.ws = new WebSocket(url);

    this.ws.onopen = (e) => {
      (...)
    };

    this.ws.onclose = (e) => {
      if (e.wasClean) {
        observer.complete();
      } else {
        observer.error(e);
      }
    };

    this.ws.onerror = (e) => {
      observer.error(e);
    }

    this.ws.onmessage = (e) => {
      observer.next(JSON.parse(e.data));
    }

    return () => {
      this.ws.close();
    };
  }).share();
}

有关详细信息,请参阅此文章(“基于事件的支持”部分):