Home > Net >  Using JS Promise as an interrupt
Using JS Promise as an interrupt

Time:08-05

I wanted to directly call a function (like interrupt handler) when a certain condition is met. I didn't want to using "polling" for that as it increases time complexity.

count = 1
p = new Promise((resolve, reject)=>{
    
    if(count == 2){
        resolve("hello")
    }
});

p.then((msg)=>{
    console.log(msg)
})

console.log("1 now");
count = 2;
I expected console.log(msg) to run when count=2 but this is not the case. It turned out that the promise is still "pending". What is the reason this happens? And how do I implement my question.

CodePudding user response:

You can use a Proxy to listen variable changes.

const count = new Proxy({
  value: 0
}, {
  set(target, prop, val) {
    // set value
    target[prop] = val;
    console.log(`count is ${val}`);

    // stop condition
    if (val == 2) {
      console.log(`count is 2(trigger stop condition)`);
    }
  }
});

// wait 2 seconds and change count.value to 1
setTimeout(() => count.value = 1, 2000);
// wait 2 seconds and change count.value to 2
// it triggers the stop condition
setTimeout(() => count.value = 2, 2000);
console.log("Waiting for changes ...");

reference: Listen to js variable change

CodePudding user response:

Proxy is one of the solutions for this. But I post another approach for your case.

You can define a custom class or object, and work with that class. Also you register your custom listener for it, and do whatever.

This is a sample of my code. Maybe it will give you some ideas for your solution.

class MyObject {
  constructor(value, func) {
    this._value = value;
    this._listener = func;
  }

  get value() {
    return this._value;
  }

  set value(newValue) {
    this._listener(newValue);
    this._value = newValue;
  }
}

function customListener(changedValue) {
  console.log(`New Value Detected: ${changedValue}`);
}

const count = new MyObject(1, customListener);

count.value = 2;

CodePudding user response:

The issue you're having is that the code inside the Promise resolves synchronously. It seems like you are assuming Promises are by default async, but that is a common async misconception. So, the code

    if(count == 2){
        resolve("hello")
    }

resolves synchronously (that is, right after you declare count to be 1) so the Promise will never be resolved. If you want to asynchronously check for a condition without using libraries, you can use setInterval:

function checkForCondition(count, time){
  return new Promise(resolve => {
    const interval = setInterval(() => {
      if (count == 2){
        resolve("The count is 2!");
      }
    } , time);
  });
}

If you call this function, the callback inside setInterval will be placed on the event loop every x ms, where x is equal to the time parameter.

  • Related