Usuwanie callbacków

Usuwanie callbacków
0

Chciałbym przerobić pewien kod napisany w js. Niestety w kodzie jest zagnieżdżonych wiele funkcji (callbacków). Jak to najlepiej uporządkować? Przykład:

database.read("value", function (result) {
process(result.text, function(success) {
if (success)
console.log("OK");
}
}

Funkcja database.read jest asynchroniczna. Chciałbym to przerobić na taki kod jednocześnie zachowując asynchroniczny charakter funkcji, tak aby odwołanie do bazy danych nie blokowało programu:

var result = database.read("value");
var success = process(result.text);
if (success)
console.log("OK");

Pixello
  • Rejestracja:około 10 lat
  • Ostatnio:4 miesiące
  • Lokalizacja:Podkarpacie
  • Postów:448
0
Piotr Poźniak
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:11
0

Nie zrobisz tego tak jak chcesz to zrobić, bo jak sam napisałeś, odwołanie się do ```
database

Kopiuj
Tak jak @Pixello napisał- promise ale nadal będziesz zagnieżdżać funkcje. Ucieczką może być zamykanie ciał callbacków w funkcje i umieszczanie ich w innym miejscu dla zwiększenia czytelności.
Jeżeli jest to ES6 i ```database.read``` jest oznaczone jako ```async``` możesz użyć ```await``` chociaż to raczej słaby pomysł bo nie wiadomo jak długo będzie czekać.
Maciej Cąderek
Maciej Cąderek
  • Rejestracja:ponad 9 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Warszawa
  • Postów:1264
0
Piotr Poźniak napisał(a):

Tak jak @Pixello napisał- promise ale nadal będziesz zagnieżdżać funkcje.

No właśnie nie, promisy są po to by można było łatwo spłaszczyć tą strukturę.

Jeżeli jest to ES6 i database.read jest oznaczone jako async możesz użyć await chociaż to raczej słaby pomysł bo nie wiadomo jak długo będzie czekać.

?? A czy Ty wiesz w ogóle jak działa async-await? Co tam będzie długo czekać?

BTW async-await nie jest częścią ES6 (ani ES7)

edytowany 1x, ostatnio: Maciej Cąderek
Piotr Poźniak
Taki przykład: https://gist.github.com/joepie91/e78ca0c9d9831de4c775 Faktycznie płasko. Nie, nie wiem jak działają, mam nadzieję, że wytłumaczysz to mi i wszystkim zainteresowanym tak, aby była jasność :)
1

Ale kombinujecie. Przypisz callbacki do zmiennych.

Maciej Cąderek
Maciej Cąderek
  • Rejestracja:ponad 9 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Warszawa
  • Postów:1264
1

@Piotr Poźniak @Uczynny Kot

Wersja z promise:

Kopiuj
function doStuff () {
  database
    .read('value')
    .then(result => process(result.text))
    .then(success => {
      if (success) {
        console.log('OK')
      }
    })
}

doStuff()

CodePen: https://codepen.io/caderek/pen/OOpRPJ?editors=0012

Wersja z async-await:

Kopiuj
async function doStuff () {
  const result = await database.read('value')
  const success = await process(result)
  
  if (result) {
    console.log('ok')
  }
}

doStuff()

CodePen: https://codepen.io/caderek/pen/MOpjev?editors=0012

Jak widać nie ma zagnieżdżeń i nic na nic nie czeka w przypadku async-await bardziej niż w wersji z callbackami i promisami (patrz kolejność wykonania console.log na CodePenie).
database.read jak widać wcale nie musi być oznaczone jako async - wystarczy, że zwróci promise (nawet jak nie zwraca i nie możesz jej przerobić to łatwo ją w promisa opakować).

Tłumaczyć jak async-await działa raczej nie będę, bo te informacje można ławo wyszukać.

A co do przykładu użytkownika @Piotr Poźniak - jest zagnieżdzony głównie ze względu na korzystanie z domknięć, możnaby go spłaszczyć przekazując dane w parametrach - czy będzie to czytelniejsze cięzko powiedzieć. Bez lepszego przeanalizowania ciężko też powiedzieć, czy rozwiązanie jest w ogóle optymalne. W każdym razie nie wiem czego ten przykład ma dowodzić ;)

@Bogaty Kret
Jasne, można po prostu przypisać callbacki do zmiennych, ale kod nadal będzie mniej czytelny, rozlazły i trzeba będzie wymyślać dodatkowe nazwy zmiennych (to akurat mniejszy problem, bo ogólnie nazwane funkcje często są wskazane, choć czasem jest to sztuczny szum jak callback jest prosty). Dlatego promisy i async-await to nie kombinowanie, a sposób na lepszej jakości kod.
Przykład z nazwanymi callbackami dla pełnego obrazu:

Kopiuj
function doStuff () {
  database.read("value", doSomethingWithResult)
}

function doSomethingWithResult (result) {
  process(result.text, displayStatus)
}

function displayStatus (success) {
  if (success) {
    console.log('OK')
  }
}

doStuff()

CodePen: https://codepen.io/caderek/pen/pdeEqa?editors=0012

edytowany 6x, ostatnio: Maciej Cąderek
Piotr Poźniak
No tak, ale kod za doStuff() i tak musi "poczekać", nie wiadomo kiedy promise się rozwiąże. Dzięki za example :)
Maciej Cąderek
Maciej Cąderek
@Piotr Poźniak No właśnie nie, zauważ, że wyświetla się najpierw "End" a potem "OK" (ostatni przykład z callbackami poprawiłem, bo nie zasymulowałem asynchronicznych wywołań).
Maciej Cąderek
Maciej Cąderek
I proszę bardzo.
Piotr Poźniak
Ja się z Tobą całkowicie zgadzam. Chodzi mi o to, że doStuff() "wykona się" szybciej, pojawi się end. W tej chwili nie możemy rozważać rzeczy, które tam się wykonują jako "zrealizowane", np. po doStuff() nie można ukryć activity indicator "bo przecież doStudd() się wykonało".
Maciej Cąderek
Maciej Cąderek
No tak, stąd właśnie ta cała maszyneria do asynchroniczności.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)