JavaScript: Jak dodać wiele elementów do tablicy?

Opublikowano: - tagi:

W jednym z poprzednich wpisów poruszałem temat: jak umieścić element w konkretnym miejscu w tablicy. W tym opiszę, jak dodać wiele elementów do tablicy, w określonym miejscu.

Mamy dwie tablice:

const tab1 = [1, 2, 3];
const tab2 = [6, 5, 4];

I chcemy dodać elementy tablicy tab2 do tab1. Na przykład tak:

[1, 2, 6, 5, 4, 3]

Możemy to zrobić za pomocą funkcji splice z klasy Array:

const tab1 = [1, 2, 3];
const tab2 = [6, 5, 4];

tab1.splice(2, 0, ...tab2);

console.log(tab1); // [1, 2, 6, 5, 4, 3]

W pierwszym parametrze informujemy splice, w którym miejscu chcemy dodać nowe elementy. W drugim podajemy 0, ponieważ nie chcemy nic kasować z tablicy. I w końcu w ostatnim parametrze podajemy listę elementów, które chcemy dodać.

splice modyfikuje tablicę, na której została ta funkcja wywołana.


Jest: Podstawowa konfiguracja

Opublikowano: - tagi:

W tym wpisie podam jak skonfigurować Jest w dwóch wersjach: dla JavaScript i TypeScript.

Konfiguracja 1: JavaScript

Krok 1: Instalacja Jest

Wywołaj komendę:

npm install --save-dev jest

Krok 2: Dodaj plik konfiguracyjny

Stwórz plik o nazwie: jest.config.json i dodaj taką zawartość:

{
  "testRegex": "((\\.|/*.)(spec))\\.js?{{content}}quot;
}

Taka konfiguracja informuje Jest, że ma uruchamiać testy, które znajdują się w plikach z rozszerzeniem: .spec.js.

Konfiguracja 2: TypeScript

Krok 1: Instalacja Jest

npm i --save-dev ts-jest @types/jest

Krok 2: Dodaj plik konfiguracyjny

Stwórz plik o nazwie: jest.config.json i dodaj taką zawartość:

{
  "preset": "ts-jest",
  "testEnvironment": "node",
  "testRegex": "((\\.|/*.)(spec))\\.ts?{{content}}quot;
}

W wersji dla TypeScript, Jest będzie szukać plików z rozszerzeniem: .spec.ts.

Mamy skonfigurowane środowisko. Czas sprawdzić, czy to działa.

Uruchomienie testów

Konfiguracja w package.json

Dodajmy jeszcze takie wpisy do pliku package.json w sekcji: scripts:

{
  "scripts": {
    "test": "jest --config ./jest.config.json",
	"test:watch": "npm run test -- --watch"
  },
}

Pierwszy skrypt uruchomi nam raz testy, bazując na naszym pliku konfiguracyjnym. Drugi skrypt zrobi to samo, ale dodatkowo będzie nasłuchiwać na ewentualne zmiany.

Uruchomienie testu

Stwórz plik z rozszerzeniem: .spec.js lub .spec.ts i dodaj zawartość do pliku:

test('First test', () => {
    expect('Foo').toEqual('Foo');
});

Na koniec wywołaj jeden ze skryptów:

npm run test

lub:

npm run test:watch

RxJS: Operator switchMap

Opublikowano: - tagi:

Operator switchMap służy do pobrania danych ze źródła typu Observable.

To, co charakteryzuje switchMap, to możliwość anulowania emisji danych z poprzedniego wywołania. W momencie, gdy nasze źródło wysyła nowe dane poprzednia subskrypcja jest anulowana - pod warunkiem że nie zakończyła się w chwili emisji nowych danych.

W przeciwieństwie do operatora mergeMap switchMap pozwala na subskrypcję, w danej chwili tylko jednego źródła danych.

Za każdym razem, gdy wyślemy dane z podanego źródła poprzednia emisja, zostanie anulowana.

Jeśli zależy Ci na:

  1. Tylko jednej subskrypcji (w danym momencie) z obiektu typu Observable
  2. Na możliwości anulowania poprzedniej emisji danych

To użyj switchMap.

Przykłady

Przykład 1

import { fromEvent, interval } from 'rxjs';
import { switchMap } from 'rxjs/operators';

const interval$ = interval(1000);

const click$ = fromEvent(document, 'click');

click$
    .pipe(
        switchMap((e) => interval$)
    )
    .subscribe(console.log);

Wynik:

0
1
2
3
(kliknięcie)
0
1
2
...

Po kliknięciu przyciskiem myszy w stronę startuje licznik co sekundę, emitując nowe dane (interval$). Drugie kliknięcie powoduje anulowanie poprzedniej subskrypcji i start nowej.

Przykład 2

import { fromEvent } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { switchMap } from 'rxjs/operators';

const API_URL = 'https://jsonplaceholder.typicode.com/todos/';

const click$ = fromEvent(document, 'click');

click$
    .pipe(
        switchMap((e) => {
            const id = parseInt(Math.random() * 20) + 1;
            return ajax.getJSON(`${API_URL}/${id}`);
        })
    )
    .subscribe(console.log);

Kliknij drugi raz odpowiednio szybko, zanim przyjdzie odpowiedź z pierwszego żądania — zostanie wysłane nowe zapytanie + anulowane zostanie poprzednie.


Comics: Technical debt

Opublikowano: - tagi:

RxJS: Operator mergeMap

Opublikowano: - tagi:

Operator mergeMap służy do pobrania danych ze źródła typu Observable przekazanego do tego operatora.

Dane z podanego źródła są wysyłane natychmiast kiedy będą dostępne. To znaczy, że kolejność odbioru danych nie jest gwarantowana. Dodatkowo dane z takiego źródła są pobierane za pomocą mergeMap równocześnie.

Przykłady

Przykład 1

import { fromEvent, interval } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

const interval$ = interval(1000);

const click$ = fromEvent(document, 'click');

click$
    .pipe(
        mergeMap((e) => interval$)
    )
    .subscribe(console.log);

Po kliknięci przyciskiem myszy na stronie zostanie wywołany obiekt Observable: interval$, który co sekundę emituje sygnał. Każde kolejne kliknięcie powoduje start emitowania danych z nowego źródła.

Czyli możemy osiągnąć taki wynik: 0, 1, 2 nowe kliknięcie: 3, 0, 4, 1, 5, 2 itd.

Przykład 2

import { fromEvent } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { mergeMap } from 'rxjs/operators';

const API_URL = 'https://jsonplaceholder.typicode.com/todos/';

const click$ = fromEvent(document, 'click');

click$
    .pipe(
        mergeMap((e) => {
            const id = parseInt(Math.random() * 20) + 1;
            return ajax.getJSON(`${API_URL}/${id}`);
        })
    )
    .subscribe(console.log);

Wystarczy klikać szybko przyciskiem myszy w stronę. Dane będą pobierane w tym samym czasie, nie czekając na zakończenie poprzedniego żądania.