Pull to refresh

Comments 22

Сколько лет прошло, а промисы все еще настолько интуитивны, что в них по-прежнему надо разбираться… Эх.
Это потому, что все примеры показываются с использованием delay(). Новички не знают как это применить потом. Показали бы как нужно промисы писать на реальных примерах.

Нет… зачем? Новички же и так с легкостью могут экстраполировать delay() до реального кода, выполняющего какую-либо обработку данных. В итоге, как обычно, получаем следующее:

Как нарисовать сову


UFO just landed and posted this here
И никто никогда не пишет что будет если .catch сунуть в середину цепочки или сделать несколько таких вызовов
.catch в середине цепочки сможет обрабатывать ошибки, которые произошли до нее.
несколько вызовов .catch в цепочке будут по цепочке обрабатывать объект ошибки, по аналогии с then
Спасибо! Ещё вопрос, вот в такой цепочке .then().catch().then() последний что нибудь получит вообще если ошибок никаких не было?
UFO just landed and posted this here

В любом случае будет вызван.
Вторым then обычно finally эмулировали, пока finally в стандарт не добавили.

UFO just landed and posted this here

Да, вы правы.


Поэтому мы теперь имеем полноценный finally вместо не всегда работающего второго then.

Promise.resolve().then(()=>{throw 1}).catch(()=>{return Promise.reject(2)}).then(()=>console.log(3)) Ну здесь нет ошибки в catch.
Получит, undefined, если catch ничего явно не вернул.
Promise.resolve().then(()=>{throw 1}).catch(()=>{return Promise.reject(2)}).then(()=>console.log(3))

Ну здесь нет ошибки в catch.
Для меня с промисами есть несколько вопросов:
1) поддержка — приходится тащить за собой полифилы
2) несовсем всегда понятно когда надо возвращать промис (передаем джейсон респонс например, все эти === «0» а где-то ===0 привет ИЕ11)
3) сложность в отлавливании ошибок — через выброса эррора, но надо знать проперти нейм в случае с фетч например это .ok

то есть очень хорошо, но прям так и хочется по старинке лапшой с коллбэками
Часто вижу как пишут «немедленно исполняется». И часто вижу как кандидаты на интервью не могут правильно ответить на вопрос, что выведет данный код:

let a = 1; Promise.resolve().then(()=>console.log('a=', a)); a = 2;

Кстати для разнообразия можно попробовать реализацию jQuery 2.x Deferred, поведение которого было поправлено в 3.x соответсвенно промисам в JS.
UFO just landed and posted this here
По спецификации, коллбек выполняется не немедленно, а асинхронно, так что будет '2'. Кто не знает и лепит туда замыкания, бывают проблемы, тем более что в JQuery работало как раз синхронно.

см п 3.1 promisesaplus.com
xitt, Своим примером вы меня окончательно запутали… Можете объяснить, что здесь происходит и почему?

var a = 1;
var b = 5;
Promise.resolve().then(()=>console.log('Promise: a=', b=a));
console.log('a==',a, 'b==',b);
a = 2;
console.log('a==',a, 'b==',b);


image

Тут два запуска: один — выполнение, второй — проверка
С удовольствием! Происходит ровно то же самое. Cначала выполняется код тот что снаружи then (вывод 1,5 и 2,5). Потом, по истечении стека вызовов, т.е. когда все текущии фунции выполнены, исполняется внутри then с присваиванием b=a. Потом вы руками исполняете еще один вывод на консоль тех же переменных уже после присваивания (2,2).
Почему интерфейс коллбэка исходной функции — в конструкторе Promise — и добавляемых по then такой разный?
В исходной есть методы resolve и reject, и мы обязаны их вызвать (иначе промис останется pending).
В вызываемых по then надо или возвращать значение, или генерировать исключение. Коллбэков в аргументах нет (практика не подтверждает).

Разумеется, можно передать во then() функцию, которая сгенерирует новый промис и воспользуется переданными коллбэками. Это может быть важно для связи с некоторыми модулями, например (кусок тестового кода, прошу игнорировать стиль и т.п.)
var promise2 = new Promise(
    function(resolve, reject) {
      var req = http.request({hostname: 'qm2a.tr2.local', port: 7380, path: '/',
            'method': 'GET'},
          function (res) {
              console.log(`STATUS: ${res.statusCode}`);
              var data = '';
              res.on('data', (chunk) => { data = data + chunk; });
              res.on('end', () => { resolve(data); }); // тут зову из откуда-то ещё далее асинхронного...
         });
      req.end();
  });


но это кажется некузявым — создавать дополнительный объект ради странностей интерфейса…

Я бы понял стандартный набор аргументов таких коллбэков — input_value (даже для исходного), resolve_cb, reject_cb.

Думаю, авторы стандарта на промисы тоже хотели универсальности. Так что им помешало?
Очень хочется добавить что например СПА приложения не терпят промис плюс фетч — электрон приложения тоже — приходится по старинке иксэйчаром подгружать контент. Возможно я некстати это сказал — простго хочется писать все с новыми апи ан нет. про выброс эксепшнов можно пример? Я не подкалываю — хотелось бы сравнить так же я делаю. try {
var navigationJsonObj = JSON.parse(navigationJsonResponse);
if (!navigationJsonObj.navbar_popular) {
throw new Error("incomplete JSON data: no navbar_popular");
} else if (!navigationJsonObj.navbar_more) {
throw new Error("incomplete JSON data: no navbar_more");
} else {
if (!navigationJsonObj.b_carousel) {
throw new Error("incomplete JSON data: no b_carousel");
}
}
navigationJsonObj = null;
} catch (err) {
console.log("cannot init processNavigationJsonResponse", err);
return;
}
А в чем проблема?
fetch(url, options)
	.then(response => {
		return response.json()
	})
	.then(json => {
		if (!json.navbar_popular) {
			throw new Error('incomplete JSON data: no navbar_popular');
		}
		......
	})
	.catch(error => {
		........
	});

Sign up to leave a comment.