Can you explain the distinction between initially connecting the subject to the observable and doing so at the end, considering that they both operate asynchronously?

I recently encountered an interesting scenario involving code where I was attempting to connect a subject to an interval observable:

const subject = new Subject();
    
// Establish the connection between the subject and the observable
interval(1000).subscribe(subject); //**Line 1**
 
subject.subscribe((value: any) => {
  console.log(`Subscriber A: Value: ${value}`);
});
 
setTimeout(() => {
   subject.subscribe((value: any) => {
       console.log(`Subscriber B: Value: ${value}`);
    });
}, 3000);

The expected output for this setup is as follows:

Subscriber A: Value: 0        
Subscriber A: Value: 1        
Subscriber A: Value: 2        
Subscriber A: Value: 3        
Subscriber B: Value: 3        
Subscriber A: Value: 4        
Subscriber B: Value: 4       
Subscriber A: Value: 5        
Subscriber B: Value: 5

This output matched my expectations. However, upon modifying the order of connecting the subject and observable, the results varied:

const subject = new Subject();
 
subject.subscribe((value: any) => {
   console.log(`Subscriber A: Value: ${value}`);
});
 
setTimeout(() => {
  subject.subscribe((value: any) => {
    console.log(`Subscriber B: Value: ${value}`);
  });
}, 3000);
    
// Connect the subject to the observable
interval(1000).subscribe(subject); //**Line 1**

The resulting output is now:

Subscriber A: Value: 0
Subscriber A: Value: 1
Subscriber A: Value: 2
Subscriber B: Value: 2
Subscriber A: Value: 3
Subscriber B: Value: 3
Subscriber A: Value: 4
Subscriber B: Value: 4
Subscriber A: Value: 5
Subscriber B: Value: 5

This differing outcome raised some questions in my mind.

  1. Why does changing the position of Line 1 lead to differences in output?

  2. In the second output, why does subscriber B begin from value 2 instead of 3 like in the first output, despite both scenarios having a 3-second delay? What fundamental concept might be eluding me here?

After testing both versions of the code, I anticipated the first output but found the discrepancy in the second output perplexing. I am eager to gain insights into the underlying cause behind such behavior.

Answer №1

Code execution takes time, in the first case the 1000ms timer starts immediately,

  • 0 emitted (at ~1000ms)
  • 1 emitted (at ~2000ms)
  • 2 emitted (at ~3000ms)
  • Subscriber B subscribed (at ~3010 ms).

It is possible that Subscriber B will miss the 3rd value (2) by just a few milliseconds.

In the second case, it's the 3000ms timer that starts first, so it will receive the value:

  • 0 emitted (at ~1010ms)
  • 1 emitted (at ~2010ms)
  • Subscriber B subscribes (~3000ms)
  • 2 emitted (at ~3010ms) (both actions occur at this point)

Also, keep in mind that timers/setTimeouts and similar functions may not run exactly at the specified time but rather "around" the given period of time. Sometimes 1000ms can be 1000ms exactly, sometimes 1005ms etc. It's not advisable to rely on exact timing for such operations.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Entering a series of predetermined value types into an array

I am currently trying to determine the best way to define a type for a specific value in TypeScript. The value in question looks like this: [{"source": "bar"}, 1483228800, 1484265600] Initially, I came up with the following approach: interface FieldSour ...

What is the method for extracting only TypeScript types from the threeJs package?

I am in the process of developing a front-end application using Webpack with threeJs functionality integrated. Previously, I would refrain from bundling threeJs to keep the size small by utilizing the threeJs UMD from a CDN link in my index.html file. Desp ...

What settings do I need to adjust in order to set up VSCode to be compatible with TypeScript

I'm currently struggling to set up VSCode with TypeScript and facing some difficulties. My focus is on the following: https://code.visualstudio.com/docs/languages/typescript It seems like after installing the compiler, VSCode should function proper ...

Troubleshooting the AngularJS digest error within a hybrid application

My hybrid app is quite bulky, using angularjs 1.7 and angular 5.x simultaneously. I have integrated ngUpgrade module to manage both apps, but I encountered a problem when trying to navigate to a different route using href, which is causing the digest cyc ...

Master the Art of Scrolling Lists in Ionic 2

I am currently using Ionic2 for my project. One of the challenges I'm facing is scrolling to the top of a list when a specific event, called messageSend, occurs. Let me show you the code for this: <ion-content padding class="messages-page-conten ...

Does adding .catch resolve a promise?

Being new to typescript / javascript, I have limited knowledge about promises. My current scenario involves creating three distinct promises within a cloud-function and subsequently returning them using Promise.all([promise1, promise2, promise3]). Each of ...

Leveraging Multiple @Input Decorators in Ionic 3 and Angular 2

Within my Ionic 3 project, I have developed a custom component called my-component. Utilizing the angular @Input functionality, data can be passed to this component with ease. In this case, I have two inputs defined as: @Input('finder') myFinder ...

Pull information from API and populate a dropdown menu in an Angular material select input

I am facing an issue with displaying data from an API in a mat select input field. I have tried to iterate over the data using a for loop but it is not working as expected. Can someone help me figure out how to properly populate the mat select input with d ...

Steps for sending angular form data to a .Net backend that requires an autoincrement id:

When trying to insert data into an SQL database through a .Net API endpoint, I encountered an issue with the request body specifying that the ID is auto-incremental. Status 500: Cannot insert explicit value for identity column in table 'StockFeed&ap ...

Customized interfaces utilizing generic components

Here is my simplified question. interface Identity{ name: string; } Next, we have a generic interface. interface State<T extends Identity>{ [T.name] : StateContainer<T> } Unfortunately, this approach fails and the following error is ...

ASP.NET Core responds with a 404 error when an Angular request is made

I am currently working with ASP.NET Core in combination with Angular 2+. In my project, I have a Controller setup like this: public class ValuesController : Controller { [HttpGet] [Route("api/values/get")] [ResponseCache(NoStore = true, Lo ...

having difficulty sending a post request with Angular

Submitting form data via HTTP post will look like this: saveDataFile(mutlidata,id,value): Observable<Response> { var _url = 'http://xxxx.xxx.xxx'; var saveDataURL = _url + '/' + id; var _this = this; ...

What is the process for integrating a JOI validator with a Firebase function?

Is there a way to incorporate JOI validator into Firebase functions as middleware? When calling a Firebase function, it looks something like this: exports.createUserAccount = region("europe-east1").https.onCall(createAccount); // createAccount is ...

Swagger Issue Resolved: Restriction on Number of Params Set

After setting up this option for my route, I noticed that when accessing the first parameter (page), it correctly returns the value entered in Swagger UI. However, when trying to access the second parameter (genre), it seems to interpret it as a string &ap ...

How can I ensure a module in Angular module federation v14 is only loaded in either the parent or child app, but not both?

I am currently utilizing Angular 14 along with module federation in my project. Within my child application, I have the following configuration: module.exports = withModuleFederationPlugin({ name: 'childapp', exposes: { './app1&apos ...

Show the string representation of the enum instead of its numerical value

Can someone help me with this issue? I am trying to retrieve the role using get role(): string but it's not returning the full role name. For example, instead of getting "Head Administrator", I only get "Administrator" returned. I know that Role["Admi ...

Intelligent prediction of data type

Is there a method in TypeScript to infer the type of a variable after a function check? const variable: string | undefined = someFunction() variable && setAppTitle(variable) // ensuring that the variable is a defined string However, in my application, thi ...

The Vue event was triggered, however there was no response

My current project consists of a Typescript + Vue application with one parent object and one component, which is the pager: //pager.ts @Component({ name: "pager", template: require("text!./pager.html") }) export default class Pager extends Vue { ...

Angular4 Material set with autocomplete feature

I recently worked on implementing a tagging system similar to StackOverflow using Angular 4's chipset and autocomplete features. Below is the code snippet I wrote for this functionality, although it seems to be encountering some issues. <mat-form- ...

Unable to load custom package in Angular 2 testing environment

I've been following the official Angular 2 testing guide on an existing project. Everything runs smoothly when I use my custom library, downloadjs, in the application. However, I encounter an error in the console during test execution: "__zone_symbol ...