在NativeScript中的Angular和Typescript中使用Web worker(多线程)是否可行?

时间:2017-02-27 14:47:56

标签: javascript angular nativescript

我目前正在开发一个基于NativeScript和Angular2的应用程序。

当我的应用程序通过HTTP获取数据时,我的屏幕会冻结,我想将获取操作放到另一个线程中。

我在网上做了很多搜索,我得到的就是javascript中的代码,如官方文档 - https://docs.nativescript.org/angular/core-concepts/multithreading-model.html

有没有办法在“Typescript”(包含Angular注入的HTTP服务的支持)中使用WebWorker实现muli-threading,而不是“Javascript”代码(来自官方文档的代码)

如果有人可以给我一些指导或提示,我们将不胜感激,如果我能得到一些相关的示例代码,那就太棒了。 谢谢。

2 个答案:

答案 0 :(得分:1)

在{N} + Angular中使用WebWorkers不应该有任何大的缺点,但请注意,目前WebWorker与Angular AoT编译并非“完全”兼容

对我来说,在使用AoT捆绑应用程序后,创建WebwWrker(var myWorker = new Worker('~/web.worker.js');)时会抛出错误。我已经看到soem在社区中讨论这个问题,并且可能通过编辑webpack.common.js并添加“加载”来解决这个问题:

{
    test: /\.worker.js$/,
    loaders: [
    "worker-loader"
    ]
}

免责声明:我没有尝试过这种方法来修复错误。

答案 1 :(得分:1)

如果有人在使用Angular和Webpack在Nativescript中添加工作程序时遇到问题,则必须遵循here中列出的步骤。

在后续步骤中要特别小心:

  • 导入工作程序时,到工作程序文件的路由位于nativescript-worker-loader!之后。

  • 在webpack.config.js中,请谨慎添加以下代码:

     {
         test: /.ts$/, exclude: /.worker.ts$/, use: [
             "nativescript-dev-webpack/moduleid-compat-loader",
             "@ngtools/webpack",
         ]
     },
    

因为您可能已经配置了AoT编译,如下所示:

{
    test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
    use: [
        "nativescript-dev-webpack/moduleid-compat-loader",
        "@ngtools/webpack",
    ]
},

,您只需要添加exclude: /.worker.ts$/,

  • 最后,有一个工作程序示例,在这种情况下,它使用Android本机库:

    • example.worker.ts:

       import "globals";
       const context: Worker = self as any;
      
       declare const HPRTAndroidSDK;
      
       context.onmessage = msg => {
           let request = msg.data;
           let port = request.port;
           let result = HPRTAndroidSDK.HPRTPrinterHelper.PortOpen("Bluetooth," + port.portName);
           context.postMessage(result);
       };
      
    • example.component.ts(../../ workers / example.worker是指向我的工作人员的相对路径):

      import * as PrinterBTWorker from "nativescript-worker-loader!../../workers/example.worker";
      import ...
      
      connect(printer: HPRTPrinter): Observable<boolean> { 
          if (this.isConnected()){
              this.disconnect(); //Disconnect first if it's already connected
          }
          return Observable.create((observer) => {
              const worker = new PrinterBTWorker();
              worker.postMessage({ port: printer });
      
              worker.onmessage = (msg: any)  => {
                  worker.terminate();
                  if (msg.data == 0) { // 0: Connected, -1: Disconnected
                      observer.next(true);
                  }
                  else {
                      observer.next(false);
                  }
              };
      
              worker.onerror = (err) => {
                  worker.terminate();
                  observer.next(false);
              }
          }).pipe(timeout(5000), catchError(err => of(false)));
      }
      

注意:我使用Observable来使对worker的调用异步,并在对本机代码的调用中添加超时,因为在无法连接到打印机的情况下(例如,它已关闭),通知将花费大约10秒钟的时间,在我看来,这一直困扰着应用程序。

重要提示:由于没有使用AoT编译工作程序,因此似乎每次更改都必须手动重新运行代码。