Pracuję z obietnicami i nie mogę zrozumieć, jak to działa w node js.

function m1(txt) {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(txt + ' - done');
      resolve()
    }, 1000);
  });
}

var foo = m1('a');

foo.then(() =>  m1('b').then(() => console.log('do something immediately after b')));

foo.then(() => m1('c'));

Oczekiwany wynik, także w konsoli Chrome.

a - done
b - done
do something immediately after b
c - done

Ale otrzymuję następujące dane wyjściowe w Node JS.

a - done
b - done
c - done
do something immediately after b

Prosimy o pomoc, nie mogę zrozumieć, dlaczego tak się dzieje i co robię, aby uzyskać oczekiwany efekt.

0
shajji 2 kwiecień 2020, 12:24

3 odpowiedzi

Najlepsza odpowiedź

Aby osiągnąć oczekiwaną wydajność, wprowadziłem następujące zmiany

function m1(txt) {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(txt + ' - done');
      resolve()
    }, 1000);
  });
}

var foo = m1('a');

foo = foo.then(() =>  m1('b').then(() => console.log('do something immediately after b')));

foo = foo.then(() => m1('c'));
0
shajji 10 kwiecień 2020, 12:04

Za każdym razem, gdy obietnica jest rozpatrywana, wszystkie (pierwszy poziom) .then() dołączone do niej są zaplanowane do wykonania w następnym tiku pętli zdarzenia . Więc w twoim przypadku:

foo.then(() => m1('b').then(() => console.log('do something immediately after b')));
foo.then(() => m1('c'));

Po rozwiązaniu problemu foo otrzymujemy pierwszy dziennik:

a - done

Wywołania zwrotne foo zostaną zaplanowane do wykonania w następnym tiku pętli zdarzeń:

| Next tick |
|:---------:|
|  then(b)  |
|  then(c)  |

Więc po wykonaniu tiku otrzymujemy następujący dziennik:

a - done
b - done
c - done

Pamiętaj, że then(b) miał wywołanie zwrotne dziennika. Dlatego podczas wykonywania wywołanie zwrotne jest dodawane do następnego taktu pętli zdarzeń. Więc następny haczyk będzie:

| Next tick |
|:---------:|
| then(log) |

Więc po wykonaniu drugiego tiku otrzymujemy Twój ostatni dziennik:

a - done
b - done
c - done
do something immediately after b
1
Rashomon 7 kwiecień 2020, 18:15

Witam, sprawdź wersję węzła. Przed v11 otrzymasz:

a - done
b - done
c - done
do something immediately after b

W wersji 11 i nowszych będzie to:

a - done
b - done
do something immediately after b
c - done

Ponieważ wprowadzono zmiany, aby dostosować się do zachowania przeglądarki. Oto pomocny artykuł na ten temat https://blog.insiderattack.net/new-changes-to-timers-and-microtasks-from-node-v11-0-0-and-above-68d112743eb3

1
majkel 7 kwiecień 2020, 18:30