简体   繁体   中英

i want to make my own event loop listener but it is blocking the call stack how to handel it like any event

i want my code to chick if a data is changed and then do some thing so i came up with this

 function autoRendring(list,unchangedlist){
    while(true){

        while(list==unchangedlist){
         //Busy waiting  
        }
          
        console.log("renderd !")
        render(list)
        unchangedlist=list
    }

how can i execute this fuchion with out blocing the main thread i have read about the event loops and how the browser handel them Separately from the main thead but i still dont know what to do

}

it just block the main thread

i want to make some thing like this in c#

using System.Threading;


int x = 0;
int y = x;

Thread t = new Thread(() => render(ref x,ref y));
Thread t2 = new Thread(() => change(ref x,ref y));


static void render(ref int x,ref int y)
{
    while (true)
    {
      
        while (x == y)
        {
      

        }
        
        Console.WriteLine(" x has changed and renderd !");
        y=x;
    }
}
static void change(ref int x,ref int y)
{
    while (true)
    {


        Console.WriteLine("inter x ");
        Console.WriteLine("x is " + x + "  and y is " + y);
        x = int.Parse(Console.ReadLine());
    }
}

t2.Start();
t.Start();

There are actually multiple issues with the code:

You have two nested while loops, the outer one is an infinite loop, and as you already might have guessed this is blocking main thread since your code does never exit. Thus no other code can be executed which could cause any change and even the UI freezes.

Since no change can happen while executing the outer loop the condition in the inner loop will not change and so the inner loop is infinite too.

For this to work you actually have to let your code execution end so the event loop can continue, changes can happen, and then your code has to be called again to evaluate the new state.

Second, list (and unchangedList ) are function parameters and so scoped locally to the function . Because of this there is no way of changing their value from outside of the function and code changing them must reside within the function/same scope.

To allow the event loop to continue you need to end your execution and queue the next execution of your code. You could use for example setInterval for this:

let list;
let unchangedList;

// initialize `list` here

// some example on how `list` could be updated
button.addEventListener('click', () => {
  // update `list`
});

function autoUpdate() {
  if (list !== unchangedList) {
    render(list);
    unchangedList = list;
  }
}

setInterval(autoUpdate, 0);

Using an interval of 0ms means to execute the callback "immediately" - but still asynchronously, ie, only to put it in the queue and continue execution. This allows the event loop to execute other queue callbacks if there are any.

Instead of executing your callback all the time though, a less CPU-heavy approach would be using requestAnimationFrame . This will queue your callback only evertime before a new frame is painted which is more efficient since with setInterval you could re-render multiple times before it is actually painted to the screen:

function autoUpdate() {
  if (list !== unchangedList) {
    render(list);
    unchangedList = list;
  }

  requestAnimationFrame(autoUpdate);
}
requestAnimationFrame(autoUpdate);

Even more efficient would be to call your code only if there actually is any change. Depending on the source of your change this could be done with appropriate event listeners like the change event of input elements or the click event for buttons and links:

inputElement.addEventListener('change', () => render(inputElement.value));
buttonElement.addEventListener('click', () => {
  let list = getUpdatedList();
  render(list);
});

If you want to observe changes in your code's variables you maybe could use observables such as with RxJS .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM