I Am Trying To Write A Simple Asynchronous Code In Js, But It Doesn't Seem To Work
Solution 1:
I am trying to write a simple asynchronous code in JS...
Nothing in your code is asynchronous. Also, in this code
takeOrder(i, order(i));
you're callingorder
and passing in i
, then passing its return value (undefined
) into takeOrder
. To pass order
into takeOrder
instead, remove the (i)
:
takeOrder(i, order);
I am trying to make it work as while the order(number) is busy executing, the program continues to display the message "Preparing order: .." and "Taking order: .."
JavaScript on browsers is run on a single main thread with access to the UI, and then zero or more web worker threads that you create. If the for
loop in your code is running on the main UI thread, nothing else can happen while it's running, because of JavaScripts run-to-completion semantics.
If the work represented by the for
loop is asynchronous, you don't have to do anything, it's just that your simulation using a for
loop wasn't an accurate model of your real work. For instance, if it's doing an ajax request.
If the work represented by the for
loop is completely synchronous like your for
loop is, I'd probably offload that for
loop to a web worker:
worker.js
:
self.addEventListener("message", function(e) {
if (e.data && e.data.command == "go") {
for (var i = 0; i < 1000000000; i++); // kill timeself.postMessage({command: "log", message: "Order: " + e.data.order + " completed"});
}
});
Your main JS file:
functionorder(number) {
var w = newWorker("worker.js");
w.addEventListener("message", function(e) {
if (e.data && e.data.command == "log") {
console.log(e.data.message);
}
w = null;
});
console.log("Queuing order: " + number);
w.postMessage({command: "go", order: number});
}
functiontakeOrder(number, cb) {
console.log("Preparing order: " + number + "");
cb(number); // Call the callback
}
console.log("Starting to accept order");
for (var i = 0; i < 3; i++) {
console.log("Taking order: " + i);
takeOrder(i, order); // Pass order as the callback
}
console.log("Job completed!");
That creates a new worker for each order, so they can overlap.
Output:
Starting to accept order Taking order: 0 Preparing order: 0 Queuing order: 0 Taking order: 1 Preparing order: 1 Queuing order: 1 Taking order: 2 Preparing order: 2 Queuing order: 2 Job completed! Order: 0 completed Order: 1 completed Order: 2 completed
Note how the main thread tells the worker to start via a message, and the worker communicates completion back to the main thread via a message.
Enhancements you could make:
order
could return aPromise
that's fulfilled when the worker finishes its work.- You could wait to post the "Job completed" until all the order promises had completed.
- The worker could post interim updates on its progress back to the main thread.
- Obviously, you could include more meaningful information in the messages between the worker threads and the main thread.
Solution 2:
The idea of web-worker did the job, and I was able to come up with equivalent node.js script
constWorker = require('webworker-threads').Worker;
var myWorker = newWorker(function() {
onmessage = function(event) {
console.log("Received order " + event.data.orderNumber + " and it is being processed");
for (var i = 0; i <= 100000000; i++); // processing time.postMessage("Order " + event.data.orderNumber + " has been successfully processed");
}
});
for (var i = 0; i < 3; i++) {
console.log("Taking order number: " + i);
myWorker.postMessage({
orderNumber: i
});
myWorker.onmessage = function(event) {
console.log(event.data);
}
}
console.log("Completed accepting orders!");
And the output is as follows:
Taking order number: 0
Taking order number: 1
Received order0and it is being processed
Taking order number: 2
Completed accepting orders!
Received order1and it is being processed
Received order2and it is being processed
Order0 has been successfully processed
Order1 has been successfully processed
Order2 has been successfully processed
Post a Comment for "I Am Trying To Write A Simple Asynchronous Code In Js, But It Doesn't Seem To Work"