Что означает функция then() в JavaScript?

Я видел код, который выглядит так:

myObj.doSome("task").then(function(env) {
    // logic
});

Откуда then() откуда?

Ответ 1

Традиционный способ обработки асинхронных вызовов в JavaScript был связан с обратными вызовами. Скажем, нам пришлось сделать три звонка на сервер, один за другим, чтобы настроить наши выражение. С обратными вызовами код может выглядеть примерно так: функция xhrGET для вызова сервера):

// Fetch some server configuration
    xhrGET('/api/server-config', function(config) {
        // Fetch the user information, if he logged in
        xhrGET('/api/' + config.USER_END_POINT, function(user) {
            // Fetch the items for the user
            xhrGET('/api/' + user.id + '/items', function(items) {
                // Actually display the items here
            });
        });
    });

В этом примере мы сначала получаем конфигурацию сервера. Затем, основываясь на этом, мы получаем информацию о текущем пользователе, а затем, наконец, получить список элементов для текущего пользователь. Каждый вызов xhrGET принимает функцию обратного вызова, которая выполняется, когда сервер отвечает.

Теперь, разумеется, чем больше уровней гнездования у нас есть, тем сложнее код читать, отлаживать, поддерживать, обновлять и в основном работать. Это обычно называют аддоном обратного вызова. Кроме того, если нам нужно обрабатывать ошибки, нам нужно, возможно, передать другую функцию каждому xhrGET, чтобы сообщить ему, что ему нужно сделать в случае ошибки. Если бы мы хотели иметь только один общий обработчик ошибок, что невозможно.

API Promise был разработан для решения этой проблемы с проблема обработки ошибок.

API Promise предлагает следующее:

  • Каждая асинхронная задача вернет объект promise.
  • Каждый объект promise будет иметь функцию then, которая может принимать два аргумента, a success обработчик и обработчик error.
  • Успех или обработчик ошибок в функции then вызывается только один раз, после асинхронная задача завершается.
  • Функция then также вернет promise, чтобы разрешить цепочку нескольких вызовов.
  • Каждый обработчик (успех или ошибка) может вернуть value, который будет передан следующему как argument, в цепочке promise s.
  • Если обработчик возвращает promise (делает другой асинхронный запрос), то следующий обработчик (успех или ошибка) вызывается только после завершения этого запроса.

Таким образом, предыдущий примерный код может перевести на что-то вроде следующего, используя promises и службы $http (в AngularJs):

$http.get('/api/server-config').then(
    function(configResponse) {
        return $http.get('/api/' + configResponse.data.USER_END_POINT);
    }
).then(
    function(userResponse) {
        return $http.get('/api/' + userResponse.data.id + '/items');
    }
).then(
    function(itemResponse) {
        // Display items here
    }, 
    function(error) {
        // Common error handling
    }
);

Распространение успеха и ошибки

Цепочка promises - очень мощный метод, который позволяет нам выполнять много функциональности, например, если услуга вызывает вызов сервера, выполните некоторую постобработку данных, а затем вернуть обработанные данные в контроллер. Но когда мы работаем с promise, есть несколько вещей, которые нам нужно иметь в виду.

Рассмотрим следующую гипотетическую цепочку promise с тремя promises, P1, P2 и P3. Каждый promise имеет обработчик успеха и обработчик ошибок, поэтому S1 и E1 для P1, S2 и E2 для P2 и S3 и E3 для P3:

xhrCall()
  .then(S1, E1) //P1
  .then(S2, E2) //P2
  .then(S3, E3) //P3

В нормальном потоке вещей, где нет ошибок, приложение будет течь через S1, S2 и, наконец, S3. Но в реальной жизни все не так гладко. P1 может столкнуться с ошибкой, или P2 может столкнуться с ошибкой, вызвав E1 или E2.

Рассмотрим следующие случаи:

• Мы получаем успешный ответ от сервера в P1, но возвращаемые данные не являются или нет данных на сервере (подумайте о пустом массиве). В такой case, для следующего обещания P2 он должен вызвать обработчик ошибок E2.

• Мы получаем ошибку для обещания P2, вызывая E2. Но внутри обработчика мы имеем данных из кеша, гарантируя, что приложение может загружаться как обычно. В таком случае, мы можем захотеть убедиться, что после E2 вызывается S3.

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

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

Если, с другой стороны, мы хотим вызвать обработчик ошибок для следующего обещания в мы можем сделать это с помощью объекта deferred и вызвать его метод reject()

Теперь Что такое отложенный объект?

Отложенные объекты в jQuery представляют собой единицу работы, которая будет завершен позднее, обычно асинхронно. Как только единица работы завершается, объект deferred может быть настроен на разрешение или неудачу.

Объект

A deferred содержит объект promise. Через объект promiseвы можете указать, что должно произойти, когда часть работы завершена. Вы сделайте это, установив функции обратного вызова на объект promise.

Отложенные объекты в JQuery: https://api.jquery.com/jquery.deferred/

Отложенные объекты в AngularJs: https://docs.angularjs.org/api/ng/service/ $q

Ответ 2

Функция

then() связана с "Javascript promises", которые используются в некоторых библиотеках или фреймворках, таких как jQuery или AngularJS.

Обещание - это шаблон для обработки асинхронных операций. Обещание позволяет вам вызвать метод, называемый "then", который позволяет вам указывать функции (функции), используемые в качестве обратных вызовов.

Для получения дополнительной информации см. http://wildermuth.com/2013/8/3/JavaScript_Promises

И для Angular promises: http://liamkaufman.com/blog/2013/09/09/using-angularjs-promises/

Ответ 3

Насколько мне известно, в javascript (на момент написания этой статьи) нет встроенного метода then().

Кажется, что независимо от того, что возвращает doSome("task"), имеет метод then.

Если вы зарегистрируете результат возврата doSome() на консоль, вы должны увидеть свойства возвращаемого.

console.log( myObj.doSome("task") ); // Expand the returned object in the
                                     //   console to see its properties.

ОБНОВЛЕНИЕ (по состоянию на ECMAScript6): -

Функция .then() включена в чистый javascript.

Из документации Mozilla здесь,

Метод then() возвращает Promise. Это два аргумента: обратный вызов функции для успешных и неудачных случаев Обещания.

Объект Promise, в свою очередь, определяется как

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

То есть, Promise выступает в качестве заполнителя для значения, которое еще не вычислено, но должно быть разрешено в будущем. И функция .then() используется для связывания функций, которые должны быть вызваны в Promise, когда она разрешена - либо как успех, либо неудача.

Ответ 4

Вот что я сделал для себя, чтобы выяснить, как все работает. Я думаю, что другие тоже могут найти этот конкретный пример полезным:

doit().then(function() { log('Now finally done!') });
log('---- But notice where this ends up!');

// For pedagogical reasons I originally wrote the following doit()-function so that 
// it was clear that it is a promise. That way wasn't really a normal way to do 
// it though, and therefore Slikts edited my answer. I therefore now want to remind 
// you here that the return value of the following function is a promise, because 
// it is an async function (every async function returns a promise). 
async function doit() {
  log('Calling someTimeConsumingThing');
  await someTimeConsumingThing();
  log('Ready with someTimeConsumingThing');
}

function someTimeConsumingThing() {
  return new Promise(function(resolve,reject) {
    setTimeout(resolve, 2000);
  })
}

function log(txt) {
  document.getElementById('msg').innerHTML += txt + '<br>'
}
<div id='msg'></div>

Ответ 5

Я подозреваю, что doSome возвращает это, то есть myObj, который также имеет метод then. Стандартная цепочка методов...

если doSome не возвращает это, будучи объектом, на котором выполнен doSome, будьте уверены, что он возвращает некоторый объект с помощью метода then...

как указывает @patrick, тогда нет() для стандартного js

Ответ 6

Ниже представлен небольшой JS_Fiddle.

, тогда представляет собой стек обратного вызова метода, который доступен после того, как обещание разрешено, оно является частью библиотеки, такой как jQuery, но теперь оно доступно на родном JavaScript и ниже приводится подробное объяснение того, как это работает.

Вы можете выполнить Promise в родном JavaScript: точно так же, как есть promises в jQuery, каждое обещание может быть сложено, а затем может быть вызвано с помощью Resolve и Reject callbacks. Вот как вы можете связать асинхронные вызовы.

Я разблокировал и отредактировал документы MSDN о статусе зарядки аккумулятора.

Что это значит, попробуйте выяснить, заряжается ли ноутбук или устройство пользователя. затем вызывается, и вы можете сделать свой успех в работе.

navigator
    .getBattery()
    .then(function(battery) {
       var charging = battery.charging;
       alert(charging);
    })
    .then(function(){alert("YeoMan : SINGH is King !!");});

Другой пример es6

function fetchAsync (url, timeout, onData, onError) {
    …
}
let fetchPromised = (url, timeout) => {
    return new Promise((resolve, reject) => {
        fetchAsync(url, timeout, resolve, reject)
    })
}
Promise.all([
    fetchPromised("http://backend/foo.txt", 500),
    fetchPromised("http://backend/bar.txt", 500),
    fetchPromised("http://backend/baz.txt", 500)
]).then((data) => {
    let [ foo, bar, baz ] = data
    console.log(`success: foo=${foo} bar=${bar} baz=${baz}`)
}, (err) => {
    console.log(`error: ${err}`)
})

Определение:: - это метод, используемый для решения асинхронных обратных вызовов

это вводится в ES6

Пожалуйста, найдите соответствующую документацию здесь Es6 Promises

Ответ 7

Функция ".then()" широко используется для обещанных объектов в программировании Asynchoronus. Для приложений Windows 8 Store. Насколько я понял, это работает как обратный вызов.

Найти подробности в этом документе http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx

Из-за причины это также может быть имя для любой другой определенной функции.

Ответ 8

doSome ( "задача" ) должен возвращать объект обещания, и это обещание всегда имеет функцию then. Итак, ваш код такой же

promise.then(function(env) {
    // logic
}); 

и вы знаете, что это обычный вызов функции-члена.

Ответ 9

В этом случае then() - это метод класса объекта, возвращаемого методом doSome().

Ответ 10

Я опаздываю примерно на 8 лет, ну... в любом случае, я действительно не знаю, что тогда делает(), но, возможно, у MDN может быть ответ. На самом деле, я мог бы понять это немного больше.

Это покажет вам всю информацию (надеюсь), вам нужно. Если кто-то уже не разместил эту ссылку. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

Формат - promise.prototype.then(). Обещание и прототип в некотором роде похожи на переменные, но не похожи на переменные в javascript. Я имею в виду, как и другие вещи, такие как navigator.getBattery(). Then(), где это на самом деле существует, но он едва используется в Интернете, показывает статусы батареи устройства, дополнительную информацию и дополнительную информацию о MDN, если вам интересно.

Ответ 11

Другой пример:

new Promise(function(ok) {
   ok( 
      /* myFunc1(param1, param2, ..) */
   )
}).then(function(){
     /* myFunc1 succeed */
     /* Launch something else */
     /* console.log(whateverparam1) */
     /* myFunc2(whateverparam1, otherparam, ..) */
}).then(function(){
     /* myFunc2 succeed */
     /* Launch something else */
     /* myFunc3(whatever38, ..) */
})