簡體   English   中英

我正在嘗試在JS中編寫一個簡單的異步代碼,但它似乎不起作用

[英]I am trying to write a simple asynchronous code in JS, but it doesn't seem to work

 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!"); 
我試圖使它在忙於執行order(number)時起作用,該程序繼續顯示消息“正在准備訂單:..”和“正在接​​受訂單:..”。我在哪里出錯?

我試圖用JS寫一個簡單的異步代碼...

您的代碼中沒有什么是異步的。 另外,在這段代碼中

takeOrder(i, order(i));

您正在調用 order並傳入i ,然后將其返回值( undefined )傳遞給takeOrder 要將order傳遞給takeOrder ,請刪除(i)

takeOrder(i, order);

我試圖使它在忙於執行order(number)時起作用,程序繼續顯示消息“正在准備訂單:..”和“正在接​​受訂單:..”

瀏覽器上的JavaScript在具有訪問UI的單個主線程上運行,然后在您創建的零個或多個Web工作者線程上運行。 如果您的代碼中的for循環在主UI線程上運行,則由於JavaScript的運行到完成的語義,在運行時其他任何事情都不會發生。

如果由代表工作for循環同步的,你沒有做任何事情,它只是你的模擬使用的for循環是不是你真正的工作的精確模型。 例如,如果它正在執行ajax請求。

如果for循環所代表的工作像for循環一樣是完全同步的,那么我可能會將for循環卸載到Web worker:

worker.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"});
  }
});

您的主要JS文件:

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!");

這將為每個訂單創建一個新工作人員,因此它們可以重疊。

輸出:

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

請注意主線程如何通過消息告訴工作程序啟動,並且工作程序通過消息將完成情況傳達回主線程。


您可以進行的增強:

  • order可能會返回一個Promise ,該Promise會在工作人員完成工作時完成。
  • 您可以等待發布“工作已完成”,直到所有訂單承諾都已完成。
  • 工作人員可以將其進度的臨時更新發布回主線程。
  • 顯然,您可以在工作線程和主線程之間的消息中包含更多有意義的信息。

網絡工作者的想法完成了這項工作,而我能夠提出等效的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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM