Я читал в блоге об обещаниях, и они показывают проблему, которой я вообще не понимаю. Блог: https: // pouchdb. ru / 2015/05/18 / we-have-a-problem-with-promises.html.

Писатель представляет 4 головоломки с графическим решением:

Головоломка # 1

doSomething().then(function () {
  return doSomethingElse();
}).then(finalHandler);

Головоломка # 2

doSomething().then(function () {
  doSomethingElse();
}).then(finalHandler);

Головоломка # 3

doSomething().then(doSomethingElse())
  .then(finalHandler);

Головоломка # 4

doSomething().then(doSomethingElse)
  .then(finalHandler);

Здесь doSomething () и doSomethingElse - это обещания.

Кто-нибудь может подробно объяснить все? По первому я получаю приказ об исполнении. Во-вторых, я не понимаю, почему doSomethingElse и finalHandler запускаются и заканчиваются одновременно. В-третьих, я не понимаю, почему doSomething и doSomethingElse запускаются одновременно. DoSomethingElse не должен начинаться в конце doSomething? На четвертом я ничего не получаю ...

2
miouri 15 Окт 2021 в 16:46

2 ответа

Лучший ответ

Головоломка 1

// doSomething() is executed and returns a promise
doSomething().then(function () {
  // when doSomething() executes successfully, execute doSomethingElse() and return the Promise
  return doSomethingElse();
}).then(finalHandler); // final handler will be executed once doSomethingElse has finished, since the promise was returned 

Головоломка 2

// doSomething() is executed and returns a promise
doSomething().then(function () {
  // when doSomething() executes successfully, execute doSomethingElse()
  doSomethingElse(); // execute doSomethingElse()
  // since there is nothing returned here, the the promise will resolve immediatly, without waiting for doSomethingElse() to complete
}).then(finalHandler); // final handler will be executed immediatly after doSomethingElse() has started to execute, without waiting for a result.

Головоломка 3

В этом случае обе функции запускаются одновременно, потому что .then ожидает, что функция имеет свой первый аргумент. doSomethingElse - это функция, а doSomethingElse() - это вызов функции. Таким образом, он вызывается немедленно, и .then() принимает в качестве первого аргумента возвращаемое значение doSomethingElse, которое является обещанием.

doSomething().then(doSomethingElse())
  .then(finalHandler);

Головоломка 4

В отличие от головоломки 3, функция doSomethingElse передается в .then() вместо возвращаемого значения doSomethingElse в головоломке 3. Это означает, что doSomethingElse будет вызываться после завершения doSomething.

// the code below is a shortcut for doSomething().then(() => doSomethingElse())
doSomething().then(doSomethingElse)
  .then(finalHandler);

Функция против вызова функции

Вам необходимо понять разницу между функцией (doSomething) и вызовом функции (doSomething()).

function doSomething() {
  return "something";
}

const func = doSomething;
const value = doSomething();

console.log(func);
console.log(value);
2
thchp 15 Окт 2021 в 14:13

Головоломки №1 и №4, а также головоломки №2 и №3 одинаковы.

В вашей головоломке №2 вы запускаете другое обещание и мгновенно возвращаетесь, не дожидаясь его. Таким образом, ваш finalHandler будет вызываться сразу после запуска doSomethingElse, а не после его завершения. Если вы этого хотите, используйте свою головоломку №1.

В вашей головоломке №3 вы передаете запущенное обещание, возвращаемое doSomethingElse (), напрямую, вместо того, чтобы указывать js на вызов этой функции, если doSomething разрешен. Если хотите, напишите так - это поможет избежать путаницы.

doSomething()
  .then(() => doSomethingElse())
  .then(() => finalHandler());
0
Joschi 15 Окт 2021 в 14:03