我试图在JS中编写一个简单的异步代码,但它似乎不起作用

时间:2016-09-10 07:59:12

标签: javascript asynchronous

function order(number) {
  console.log("Queuing order: " + number);
  for (var i = 0; i < 1000000000; i++); // kill time
  console.log("Order: " + number + " completed");
}

function takeOrder(number, cb) {
  console.log("Preparing order: " + number + "");
}
console.log("Starting to accept order");
for (var i = 0; i < 3; i++) {
  console.log("Taking order: " + i);
  takeOrder(i, order(i));
}
console.log("Job completed!");
我正在尝试让它工作,当订单(数字)忙于执行时,程序继续显示消息“准备订单:..”和“接受订单:..” 我哪里错了?

2 个答案:

答案 0 :(得分:2)

  

我正在尝试在JS中编写一个简单的异步代码...

您的代码中没有任何内容是异步的。此外,在此代码中

takeOrder(i, order(i));

致电 order并传递i,然后将其返回值(undefined)传递给takeOrder。要将order传递给takeOrder,请删除(i)

takeOrder(i, order);
  

我正在尝试让它工作,当订单(数字)忙于执行时,程序继续显示消息&#34;准备订单:..&#34;和&#34;接受订单:..&#34;

浏览器上的JavaScript在单个主线程上运行,可以访问UI,然后是您创建的零个或多个web worker个线程。如果代码中的for循环在主UI线程上运行,则由于JavaScripts运行完成语义,在运行时不会发生任何其他情况。

如果for循环代表的工作是 a 同步,那么您不必做任何事情,只需要使用{{{ 1}}循环并不是你真实工作的准确模型。例如,如果它正在执行ajax请求。

如果for循环表示的工作与for循环完全同步,我可能会将for循环卸载到网络工作者:

for

worker.js

您的主要JS档案:

self.addEventListener("message", function(e) {
  if (e.data && e.data.command == "go") {
    for (var i = 0; i < 1000000000; i++); // kill time
    self.postMessage({command: "log", message: "Order: " + e.data.order + " completed"});
  }
});

为每个订单创建一个新工人,因此它们可以重叠。

输出:

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

注意主线程如何告诉worker通过消息启动,并且worker通过消息将完成传回主线程。

您可以进行的改进:

  • function order(number) { var w = new Worker("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}); } function takeOrder(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!"); 可以在工作人员完成工作后返回order
  • 您可以等待发布&#34;工作完成&#34;直到所有订单承诺都已完成。
  • 工作人员可以将其进度的临时更新发回主线程。
  • 显然,您可以在工作线程和主线程之间的消息中包含更有意义的信息。

答案 1 :(得分:0)

网络工作者的想法完成了这项工作,我能够提出等效的node.js脚本

const Worker = require('webworker-threads').Worker;
var myWorker = new Worker(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!");

输出如下:

Taking order number: 0
Taking order number: 1
Received order 0 and it is being processed
Taking order number: 2
Completed accepting orders!
Received order 1 and it is being processed
Received order 2 and it is being processed
Order 0 has been successfully processed
Order 1 has been successfully processed
Order 2 has been successfully processed