0

I read: Design pattern for managing multiple asynchronous JavaScript operations but this does not have a clear resolution and also the question is very old and jQuery dependent.

My situation is somewhat similar, it can not be resolved with promise.all as the asynchronous task is being invoked by a users as often as they like, as frequently as they like.

What I am trying to do is see when all async operations are idle. When is asyncTest truly doing nothing.

This has got to be a common check, just wondering how it is done.

The user can invoke asyncTest at anytime.

class TestApp {

  processing = false;

  asyncTest() {
    this.processing = true;
    setTimeout(() => {
      this.processing = false;
    }, 500);
  }
}

As you can see this will have collisions.

Other async tasks may want to see if this is processing. I considered the following but it just feels so darn hacky

EDIT: Well, based on comments by Simon K below and the fact that it is clean and working, until I hear otherwise from the community, my original solution below seems to be fine:

class TestApp {

  _processCount = 0;

  get isProcessing() {
    return this._processCount > 0;
  }


  asyncTest() {
    this._processCount++;
    setTimeout(() => {
      this._processCount--;
    }, 500);
  }
}

Note: Angular 5 Project. Somewhat familiar with Rx/js but not so pro with it, I recently realized how powerful it is and have a suspicion it would help here.

Many Thanks!

1
  • 1
    There's absolutely nothing wrong with using a simple solution here (which really isn't hacky). It's definitely the most readable and any solution using Rx/js would end up keeping some list of running processes anyway, which is worse than keeping a simple count. Commented Feb 22, 2018 at 2:53

1 Answer 1

0

If you are using rxjs, this can be easily solved by using a Subject. A Subject is both an Observer and Observable - put in simple terms, it can modify its own value (state) and others may subscribe to it and see if the value has really changed.

class TestApp {

    // initialize the variable with an initial value of false
    processing = new BehaviourSubject<boolean>(false);

    asyncTest() {
        //just use .next() to update the subject
        this.processing.next(true);
    }

    get isProcessing() {
        //now you can just subscribe to the subject and check its current value
        this.processing.subscribe(processingStatus => {
            console.log(processingStatus)//will give you true or false
        })
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

How is this any different to just assigning a boolean to a variable? Either way you can only read the latest value and if ANY process finishes, it will say none are processing even though others could still be running.
@SimonK not sure what you are trying to convey but, these are minimal code to demonstrate the usefulness of reactive programming. OP stated that asyncTest() can be invoked by user at any point of time. How and when .next() is called is entirely up to OP himself
I'm not trying to be a tool here but you haven't actually answered the question and your posted code doesn't get the OP any closer to the answer. If we use your suggestion it will go like this: Process 'A' starts so we .next(true); Process 'B' starts, .next(true); Process 'A' finishes, .next(false); At this stage, isProcessing() will return false even though Process 'B' is running.
like I said, I am just demonstrating how to use the .next(). OP never states there is ProcessA or ProcessB or ProcessC, and I am not going to assume anything. The method in asyncTest() there, as written in the comments, is the place where he can update the values there. He can create any other functions/methods to update the subject, yes; but that's entirely up to him.