freeCodeCamp/guide/russian/javascript/promises/index.md

9.0 KiB
Raw Blame History

title localeTitle
Promises обещания

обещания

JavaScript однопоточный, что означает, что два бита скрипта не могут работать одновременно; они должны бежать один за другим. Promise - это объект, который представляет собой возможное завершение (или отказ) асинхронной операции и ее итоговое значение.

var promise = new Promise(function(resolve, reject) { 
  // do thing, then… 
 
  if (/* everything worked */) { 
    resolve("See, it worked!"); 
  } 
  else { 
    reject(Error("It broke")); 
  } 
 }); 

В одном из этих состояний существует обещание

  • Ожидание: начальное состояние, ни выполнено, ни отклонено.
  • Выполнено: операция успешно завершена.
  • Отклонено: операция завершилась неудачно.

Объект Promise работает как прокси-сервер для значения, которое не обязательно известно при создании обещания. Это позволяет связать обработчики с вероятным результатом успешной асинхронной операции или причиной сбоя. Это позволяет асинхронным методам возвращать такие значения, как синхронные методы: вместо немедленного возврата окончательного значения асинхронный метод возвращает обещание предоставить значение в какой-то момент в будущем.

Использование 'Then' (Promise Chaining)

Чтобы выполнить несколько асинхронных вызовов и синхронизировать их один за другим, вы можете использовать цепочку слияния. Это позволяет использовать значение из первого обещания в последующих последующих обратных вызовах.

Promise.resolve('some') 
  .then(function(string) { // <-- This will happen after the above Promise resolves (returning the value 'some') 
    return new Promise(function(resolve, reject) { 
      setTimeout(function() { 
        string += 'thing'; 
        resolve(string); 
      }, 1); 
    }); 
  }) 
  .then(function(string) { // <-- This will happen after the above .then's new Promise resolves 
    console.log(string); // <-- Logs 'something' to the console 
  }); 

API обещаний

В классе Promise существует 4 статических метода:

  • Promise.resolve
  • Promise.reject
  • Promise.all
  • Promise.race

Обещания могут быть соединены вместе

При написании обещаний для решения конкретной проблемы вы можете связать их вместе, чтобы сформировать логику.

var add = function(x, y) { 
  return new Promise((resolve,reject) => { 
    var sum = x + y; 
    if (sum) { 
      resolve(sum); 
    } 
    else { 
      reject(Error("Could not add the two values!")); 
    } 
  }); 
 }; 
 
 var subtract = function(x, y) { 
  return new Promise((resolve, reject) => { 
    var sum = x - y; 
    if (sum) { 
      resolve(sum); 
    } 
    else { 
      reject(Error("Could not subtract the two values!")); 
    } 
  }); 
 }; 
 
 // Starting promise chain 
 add(2,2) 
  .then((added) => { 
    // added = 4 
    return subtract(added, 3); 
  }) 
  .then((subtracted) => { 
    // subtracted = 1 
    return add(subtracted, 5); 
  }) 
  .then((added) => { 
    // added = 6 
    return added * 2; 
  }) 
  .then((result) => { 
    // result = 12 
    console.log("My result is ", result); 
  }) 
  .catch((err) => { 
    // If any part of the chain is rejected, print the error message. 
    console.log(err); 
  }); 

Это полезно для использования парадигмы функционального программирования . Создавая функции для манипулирования данными, вы можете объединить их вместе, чтобы собрать окончательный результат. Если в любой точке цепочки функций значение отклоняется, цепь перейдет к ближайшему обработчику catch() .

Для получения дополнительной информации о функциональном программировании: функциональное программирование

Генераторы функций

В последних выпусках JavaScript ввел больше способов изначально обрабатывать обещания. Одним из таких способов является генератор функций. Генераторы функций являются «правдоподобными» функциями. При использовании с Promise генераторы могут сделать использование намного проще для чтения и появиться «синхронно».

const myFirstGenerator = function* () { 
  const one = yield 1; 
  const two = yield 2; 
  const three = yield 3; 
 
  return 'Finished!'; 
 } 
 
 const gen = myFirstGenerator(); 

Вот наш первый генератор, который вы можете видеть по синтаксису function* . Объявленная переменная gen не будет запускать myFirstGenerator , но вместо этого «этот генератор будет готов к использованию».

console.log(gen.next()); 
 // Returns { value: 1, done: false } 

Когда мы запустим gen.next() он отключит генератор и продолжит работу. Поскольку это первый раз, когда мы вызвали gen.next() он будет работать с yield 1 и приостанавливаться до тех пор, пока мы снова не назовем gen.next() . Когда вызывается yield 1 , он возвращает нам value которое было получено, и независимо от того, done ли генератор.

console.log(gen.next()); 
 // Returns { value: 2, done: false } 
 
 console.log(gen.next()); 
 // Returns { value: 3, done: false } 
 
 console.log(gen.next()); 
 // Returns { value: 'Finished!', done: true } 
 
 console.log(gen.next()); 
 // Will throw an error 

Поскольку мы продолжаем называть gen.next() он будет продолжать идти на следующий yield и приостанавливать каждый раз. После того, как у вас больше нет yield , он продолжит работу с остальной частью генератора, которая в этом случае просто вернется 'Finished!' , Если вы снова вызове gen.next() , он будет генерировать ошибку по завершении работы генератора.

Теперь представьте, что если каждый yield в этом примере был Promise , сам код выглядел бы крайне синхронно.

Promise.all (iterable) очень полезен для множественного запроса к другому источнику

Метод Promise.all (iterable) возвращает единственное обещание, которое разрешает, когда все обещания в итерабельном аргументе разрешены или когда аргумент итерации не содержит никаких обещаний. Он отвергает причину первого обещания, которое отвергает.

var promise1 = Promise.resolve(catSource); 
 var promise2 = Promise.resolve(dogSource); 
 var promise3 = Promise.resolve(cowSource); 
 
 Promise.all([promise1, promise2, promise3]).then(function(values) { 
  console.log(values); 
 }); 
 // expected output: Array ["catData", "dogData", "cowData"] 

Больше информации

Для получения дополнительной информации о обещаниях: обещания