Observable is part of the asynchronous programming core of the Rxjs library. How does it differ from Rxjs

Observables are introduced

RxJS is a library for writing asynchronous and event-based programs using observable sequences. It provides a core Observable type, auxiliary types (Observer, Schedulers, Subjects), and operators inspired by [Array#extras] (Map, Filter, reduce, every, etc.), These array operators can handle asynchronous events as collections. ———— quotes the introduction of Rxjs Chinese website — Rxjs official website

Observable (Observable)

See the JavaScript design pattern — observe, subscribe

  • The basic concepts used to address asynchronous event management in RxJS are:
  • -Observable: Represents a concept that is a callable collection of future values or events.
  • Observer: A collection of callback functions that know how to listen for values provided by an Observable.
  • Subscription: Represents an Observable execution, and is used primarily to cancel an Observable execution.
  • Operators: A functional programming style pure function that uses Operators such as map, filter, concat, flatMap, and so on to process collections.
  • Subject: Equivalent to An EventEmitter and the only way to multiplexe a value or event to multiple observers.
  • Schedulers: A centralized scheduler that controls concurrency and allows us to coordinate calculations as they occur, such as setTimeout or requestAnimationFrame or its

The use of observables

/ / observables
import { Observable } from 'rxjs'
// Create an Observable
let Ob1 = new Observable((observer) = > {
  observer.next('observable')
})
Ob1.subscribe((value) = > {
  console.log(value)
})
Copy the code

The use of Promise

let Pro1 = new Promise((resolve,reject) = >{
  resolve(1)
  //reject(2)
}
Pro1.then(value= >{
  console.log(value)
})
Copy the code

Observables and function

function foo(a) {
  console.log('Hello');
  return 42;
}

var x = foo.call(); // equivalent to foo()
console.log(x);
var y = foo.call(); // equivalent to foo()
console.log(y);
//"Hello"
/ / 42
//"Hello"
/ / 42
//Rewrite the above code with Observables:var foo = Rx.Observable.create(function (observer) {
  console.log('Hello');
  observer.next(42);
});

foo.subscribe(function (x) {
  console.log(x);
});
foo.subscribe(function (y) {
  console.log(y);
});
//"Hello"
/ / 42
//"Hello"
/ / 42
//
Copy the code

Because functions and Observables are lazy operations. If you don’t call the function, console.log(‘Hello’) will not execute. The same goes for the Observables, and if you don’t “call” it (using subscribe), console.log(‘Hello’) won’t execute either. In addition, “calling” or “subscribing” is a separate operation: two function calls trigger two separate side effects, and two Observable subscriptions trigger two separate side effects. EventEmitters share side effects and are executed as early as possible with or without subscribers, while Observables, on the other hand, do not share side effects and are delayed execution.

The difference between

Why Rxjs

Promises can only convert a data state from pending to resoloved or Rejected. Rxjs can handle multiple data with complete and error states but Rxjs also has the next method. An Observable is lazy and output only when it needs to subscribe. The promise internal state is uncontrollable and cannot be terminated after execution. An Observable can define how to cancel an asynchronous method. Consider the following scenario:

Enter characters in the input box, press Enter to send a request, and return the result as a Todo item. If the return or Add button is pressed again before the request returns the result, nothing is done if it is the same, and if it is different, the last request is cancelled and a new request is sent. (the actual scene is often sends an HTTP request the request returns is slow, inspection business with heartbeat (sender according to certain rules (periodically send, send free, etc.) to the receiving party to send the news of the fixed format, the receiving party after receiving the message reply to a fixed format, if long time no received, such as the heartbeat cycle three times, The current connection is considered invalid and the connection is disconnected. If there is no return in the previous heartbeat interval, the request will be called again, and the return of the previous request needs to be discarded. In this case, the interface with different parameters may be called, resulting in data inconsistency.) For the Promise implementation, we not only need to maintain a timer timer, but also maintain a global variable.

For example, we need to listen to the page scrolling event, make some logical operations, this is the event will be called too frequently, resulting in the phenomenon of page lag. When implemented with native JS, you need to implement a throttling or shaking function, and maintain a timer internally by implementing a closure function. This can be easily solved in Rxjs by the operator debounce

Synchronous and Asynchronous

The first difference is that a Promise is a solution to asynchronous programming, whereas an Observable can be synchronous or asynchronous

//Observable executes synchronously
var foo = Rx.Observable.create(function (observer) {
  console.log('Hello')
  observer.next(42)
  observer.next(100) // "return" another value
  observer.next(200) // You can "return" the value again
})

console.log('before')
foo.subscribe(function (x) {
  console.log(x)
})
/*
"before"
"Hello"
42
100
200
"after"
*/
console.log('after')

const Observable = require('rxjs/Observable').Observable;

const observable = new Observable((observer) = > {
    // observer.next(5);
    setTimeout(() = > {
        observer.next(5); })}); observable.subscribe(value= > console.log(value + '! '));
console.log('And now we are here.');

//This is if it's directly next5, the output is5! -> And now we are heresetTimeout next 5And now we are here.->5
Copy the code
Single and multiple values

The next() method in the Observable is similar to promise.resolve (), but if the resolve() method inside the Promise() succeeds, the following does not execute, which means that the Observable can consistently emit many values. A Promise can only fire one value and then it’s over

const promise1 = new Promise((resolve) = > {
  console.log(' I am promise ')})const observable1 = new Observable(() = > {
  console.log('I am Observable! ')})Copy the code

The console.log in Promise executes, but the code in Observable does not output, only after subscribing

Cancellation of asynchronous execution task

Promise execution is unsubscribe by default, and An Observable can be unsubscribe() with subscribe’s unsubscribe() method because in a Promise. Then () returns a new Promise object, Observable+ SUBSCRIBE returns a Subscription object

const Observable = require('rxjs/Observable').Observable;

const observable = new Observable((observer) => {
    let i = 0;
    const token = setInterval(() => {
        observer.next(i++);
    }, 1000);

    return () => clearInterval(token);
});

const subscription = observable.subscribe(value => console.log(value + '! '));

setTimeout(() => {
    subscription.unsubscribe();
}, 5000)

/ / the result

0!
1!
2!
3!
//Observable

Copy the code
Execute once and multiple times

A Promise only executes resolve() once, while an Observable executes the code in the observed object once per subscription


//Promise
let time;
const waitOneSecondPromise = new Promise((resolve) => {
    console.log('promise call')
    time = new Date().getTime();
    setTimeout(() => resolve('hello world'), 1000);
});

waitOneSecondPromise.then((value) => {console.log( 'First time', value, new Date().getTime() - time)});

setTimeout(() => {
    waitOneSecondPromise.then((value) => {console.log('The second time', value, new Date().getTime() - time)});
}, 5000)

// The output is a Promise CallFirst hello world1007Hello world5006

//Observable

const Observable = require('rxjs/Observable').Observable;

let time;
const waitOneSecondObservable = new Observable((observer) => {
    console.log('I was called');
    time = new Date().getTime();
    setTimeout(() => observer.next('hey girl'), 1000);
});

waitOneSecondObservable.subscribe((value) => {console.log( 'First time', value, new Date().getTime() - time)});

setTimeout(() => {
    waitOneSecondObservable.subscribe((value) => {console.log( 'The second time', value, new Date().getTime() - time)});
}, 5000)

/ / outputI was called the first time hey girl1003I was called second time hey girl1003
Copy the code
tool

Observable provides a number of utility functions. The common Filter and Map functions are shown below

let stream2$ =
  new Observable() <
  number >
  ((observer) = > {
    let count = 0
    let interval = setInterval(() = > {
      observer.next(count++)
    }, 1000)
    return () = > {
      clearInterval(interval)
    }
  })
stream2$.subscribe((value) = > console.log('Observable>' + value))
stream2$
  .pipe(filter((val) = > val % 2= =0))
  .subscribe((value) = > console.log('filter>' + value))
stream2$
  .pipe(map((value) = > value * value))
  .subscribe((value) = > console.log('map>' + value))
Copy the code
conclusion
  • An Observable is lazy, only a subscription is printed, and an Observable can accept multiple values. Promise can only be resolved once.
  • Promise internal resolve must be asynchronous, whereas Observable is free to play
  • Promises are only executed once, after they are created, and cannot be executed repeatedly, whereas Observables are executed once per subscription, and if you want to execute only once, you can use a share.
  • Promises can’t be canceled, but Observables can