代码之家  ›  专栏  ›  技术社区  ›  Lajos Arpad

如何使用blob创建SharedWorker?

  •  0
  • Lajos Arpad  · 技术社区  · 6 年前

    我想创建一个共享的工作人员,正如一本好书的一章所述: https://github.com/getify/You-Dont-Know-JS/blob/master/async%20%26%20performance/ch5.md

    我能想出一个很好的例子 网络工作者:

    function createAsker(limit) {
        var blob = new Blob(["onmessage = function(e) { " +
                               "if (self.higher === undefined) self.higher = " + limit + "; " +
                               "if (self.lower === undefined) self.lower = 1;" +
                               "if (e.data === 'correct') { " +
                                 "postMessage('Party time'); " +
                               "} else {" +
                                 "if (e.data === 'greater') self.lower = parseInt((self.lower + self.higher) / 2);" +
                                 "if (e.data === 'lower') self.higher = parseInt((self.lower + self.higher) / 2);" +
                                 "postMessage(parseInt((self.lower + self.higher) / 2));" +
                               "}" +
                             "}"]);
        var blobURL = window.URL.createObjectURL(blob);
        var worker = new Worker(blobURL);
        return worker;
    }
    
    var asker = createAsker(1000);
    
    function createAnswerer(limit) {
        var blob = new Blob(["onmessage = function(e) { " +
                                "postMessage((e.data == " + limit + ") ? 'correct' : ((e.data < " + limit + ") ? 'greater' : 'lower'));" +
                             "}"]);
        var blobURL = window.URL.createObjectURL(blob);
        var worker = new Worker(blobURL);
        return worker;
    }
    
    var answerer = createAnswerer(42);
    
    asker.onmessage = function(e) {
      console.log('Asker says: ' + e.data);
      if (e.data !== "Party time") {
        setTimeout(function() {answerer.postMessage(e.data)}, 1000);
      }
    };
    
    answerer.onmessage = function(e) {
      console.log('Answerer says: ' + e.data);
      setTimeout(function() {asker.postMessage(e.data)}, 1000);
    };
    
    asker.postMessage('start');
    

    然而,我很难创建一个共享的工作人员。我尝试用以下代码创建一个:

    function createWorker() {
        var blob = new Blob(['addEventListener( "connect", function(evt){ ' +
                                'var port = evt.ports[0]; ' +
                                'port.addEventListener( "message", function(evt){' +
                                  'port.postMessage( .. );debugger;' +
                                '} );' +
                                'port.start();' +
                              '} );']);
        var blobURL = window.URL.createObjectURL(blob);
        var w = new SharedWorker(blobURL);
        return w;
    }
    
    var w = createWorker();
    
    w.port.start();
    
    w.port.onmessage = function(e) {
      console.log(e.data);
    };
    
    w.port.onmessage('foobar');
    

    在发送foobar的消息之后,我希望我的共享工作线程发布一条消息,或者至少我希望被调试器引导到代码中,但是,当我运行这段代码时,控制台会给出两个未定义的响应。

    0 回复  |  直到 6 年前
        1
  •  3
  •   Evgeniy Generalov    5 年前

    Base64编码提供一个永久的URL,直到源代码发生更改。

    const source = 'importScript("https://anotherhost/worker.js")';
    const url = 'data:application/javascript;base64,' + btoa(source);
    const worker = new SharedWorker(url);
    

    它至少能在Chrome73和Firefox66上使用。

    有一个 limit to the length 编码的URL的大约65千字节。