Web Worker multithreaded API research _javascript techniques in JavaScript

Source: Internet
Author: User

HTML5 supports APIs such as Web worker, allowing Web pages to execute multithreaded code in a secure environment. However, web worker is actually a lot of restrictions, because it can not really share the memory data, only through the message to do status notifications, so even can not be called the true meaning of "multithreading."

Web worker interface is very inconvenient to use, it basically takes a sandbox, run a separate JS file in the sandbox, through PostMessage and onmessge to communicate with the main thread:

Copy Code code as follows:

var worker = new Worker ("My.js");
var bundle = {message: ' Hello world ', id:1};
Worker.postmessage (bundle); PostMessage can pass a serializable object to the past
Worker.onmessage = function (evt) {
Console.log (Evt.data); Compare objects in the worker and in the main thread
Console.log (bundle); {message: ' Hello world ', id:1}
}

Copy Code code as follows:

In My.js
OnMessage = function (evt) {
var data = Evt.data;
data.id++;
PostMessage (data); {message: ' Hello world ', id:2}
}

The results can be found, the ID of the data obtained in the thread is incremented, but after being returned, the ID in the bundle of the main thread is not changed, so the objects passed in the threads actually copy a copy, so that the thread does not share the data and avoids the read-write conflict, so it is safe. The cost of ensuring thread safety is to limit the ability to manipulate the main thread object in a thread.

Such a limited multithreaded mechanism is inconvenient to use, and we certainly hope that the worker can support the ability to make the code appear to operate multithreading at the same time, for example, to support code that looks like this:

Copy Code code as follows:

var worker = new Threadworker (bundle/*shared obj*/);

Worker.run (function (bundle) {
Do sth in worker thread ...
This.runonuithread (function (bundle/*shared obj*/) {
Do sth in main UI thread ...
});
//...
});

In this code, after we start a worker, we can get arbitrary code to run in the worker, and when we need to manipulate the UI thread (such as reading and writing DOM), we can go back to the main thread execution via This.runonuithread.

So how do you implement this mechanism? Look at the following code:

Copy Code code as follows:

function Workerthread (sharedobj) {
This._worker = new Worker ("Thread.js");
This._completes = {};
this._task_id = 0;
This.sharedobj = Sharedobj;

var self = this;
This._worker.onmessage = function (evt) {
var ret = Evt.data;
if (ret.__ui_task__) {
Run on UI task
var fn = (new Function ("return" +ret.__ui_task__)) ();
FN (ret.sharedobj);
}else{
Self.sharedobj = Ret.sharedobj;
Self._completes[ret.taskid] (ret);
}
}
}

WorkerThread.prototype.run = function (task, complete) {
var _task = {__thread_task__:task.tostring (), SHAREDOBJ:THIS.SHAREDOBJ, taskid:this._task_id};
this._completes[this._task_id++] = complete;
This._worker.postmessage (_task);
}

The above code defines a Threadworker object that creates a Web Worker running Thread.js, saves the shared object sharedobj, and processes the messages that Thread.js sends back.

If a ui_task message is returned in the thread.js, then the function that runs the message is executed, otherwise the run complete callback is performed to see how Thread.js is written:

Copy Code code as follows:

OnMessage = function (evt) {
var data = Evt.data;

if (data && data.__thread_task__) {
var task = data.__thread_task__;
try{
var fn = (new Function ("return" +task)) ();

var ctx = {
Threadsignal:true,
Sleep:function (interval) {
Ctx.threadsignal = false;
SetTimeout (_run, interval);
},
Runonuithread:function (Task) {
PostMessage ({__ui_task__:task.tostring (), sharedObj:data.sharedObj});
}
}

function _run () {
Ctx.threadsignal = true;
var ret = Fn.call (CTX, data.sharedobj);
PostMessage ({error:null, Returnvalue:ret, __thread_task__:task, SHAREDOBJ:DATA.SHAREDOBJ, taskId:data.taskId});
}

_run (0);

}catch (ex) {
PostMessage ({error:ex.toString (), Returnvalue:null, SHAREDOBJ:DATA.SHAREDOBJ});
}
}
}

As you can see, Thread.js receives the message from the UI thread, the most important of which is the Thread_task, which is the "task" that the UI thread is passing through that requires the worker thread to perform, because the function is not serializable, so the string is passed, The worker thread performs the task of the main thread commit by parsing the string into a function (note that the shared object is sharedobj in the task), and the return result is passed to the UI thread after execution. Let's take a closer look. In addition to the return value ReturnValue, the shared object Sharedobj is also returned, and as the worker thread and the UI thread do not share the object, we synchronize the objects on both sides by assigning the value (is this thread safe?). Why? )

You can see that the whole process is actually not complicated, and after that, this threadworker can have the following two uses:

Copy Code code as follows:

var T1 = new Workerthread ({i:100}/*shared obj*/);

        setinterval (function () {
             T1.run (function (sharedobj) {
                     return sharedobj.i++;
               },
                 function (r) {
                     Console.log ("t1>" + R.returnvalue + ":" + r.error);
               }
           );
       }, 500);
var t2 = new Workerthread ({i:50});

T2.run (function (sharedobj) {
while (this.threadsignal) {
sharedobj.i++;

This.runonuithread (function (sharedobj) {
W ("Body ul"). AppendChild ("<li>" +sharedobj.i+ "</li>");
});

This.sleep (500);
}
return sharedobj.i;
}, Function (r) {
Console.log ("t2>" + R.returnvalue + ":" + r.error);
});

This use of the form and semantics of the code has a good structure, flexibility and maintainability.

All right, about the usage of web worker. Here, interested students can take a look at this project: Https://github.com/akira-cn/WorkerThread.js (because the worker needs to use the server test, I deliberately put a cottage in the project Httpd.js, is a very simple HTTP service JS, directly with node can run up.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.