Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 11.07.2017, 13:23
Интересующийся
Отправить личное сообщение для SergeyERjs Посмотреть профиль Найти все сообщения от SergeyERjs
 
Регистрация: 03.07.2017
Сообщений: 19

Рекурсия промисов. Все правильно?
Всем привет.
Прошу проверить код.

Было так:
<html>
<head>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script>
'use strict'
var obj = {count: 0, maxCount: 5};
while (isNeedContinue(obj)) {
	doAnything();
	console.log("Что-то еще...");
}
function doAnything() {
	obj.count++;
	console.log("doAnything", obj.count);
}
function isNeedContinue(obj) {
	console.log("isNeedContinue", obj, obj.count <  obj.maxCount);
	return obj.count <  obj.maxCount
}
</script>
</head>
</html>

Функция doAnything стала асинхронной.
Переделал так:
<html>
<head>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script>
'use strict'
var obj = {count: 0, maxCount: 5};
*!*$.when((function recursive() {*/!*
	*!*if*/!* (isNeedContinue(obj)) {
		*!*return*/!* doAnything()*!*.then(function () {*/!*
			console.log("Что-то еще...");
			*!*return recursive()*/!*
		})
	}
})())
	.done(function (res) {
		console.log("Done", res);
	})
	.fail(function (err) {
		console.log("Fail", err);
	});
function doAnything() {
	*!*var deferred = $.Deferred();*/!*
	*!*setTimeout(function () {*/!*
		obj.count++;
		console.log("doAnything", obj.count);
		//if (obj.count==3) deferred.reject(new Error("err!"));
		*!*deferred.resolve(obj);*/!*
	*!*}, 1000)*/!*
	*!*return deferred.promise()*/!*
}
function isNeedContinue(obj) {
	console.log("isNeedContinue", obj, obj.count <  obj.maxCount);
	return obj.count <  obj.maxCount
}
</script>
</head>
</html>


Все ли путем?
Технически, все вроде работает. Но вдруг я что-то упустил?
Осваиваю JS, буду благодарен за любую конструктивную критику.

Последний раз редактировалось SergeyERjs, 11.07.2017 в 13:48.
Ответить с цитированием
  #2 (permalink)  
Старый 11.07.2017, 16:58
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

дефереды безнадежно устарели. Забудь о них.

лучше юзать нативные промисы. https://jsfiddle.net/jgk0v70f/
Ответить с цитированием
  #3 (permalink)  
Старый 11.07.2017, 17:09
Интересующийся
Отправить личное сообщение для SergeyERjs Посмотреть профиль Найти все сообщения от SergeyERjs
 
Регистрация: 03.07.2017
Сообщений: 19

Цитата:
лучше юзать нативные промисы
В IE не работает, а это критично. На babel переходить пока не готов.

За пример спасибо.
Ответить с цитированием
  #4 (permalink)  
Старый 11.07.2017, 18:25
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

Сообщение от SergeyERjs
В IE не работает, а это критично.
полифилл же есть.
добавь полифилл, и всё заработает. не нужен тут никакой бабель (к счастью).
Ответить с цитированием
  #5 (permalink)  
Старый 12.07.2017, 12:09
Интересующийся
Отправить личное сообщение для SergeyERjs Посмотреть профиль Найти все сообщения от SergeyERjs
 
Регистрация: 03.07.2017
Сообщений: 19

Alexandroppolus,
а не подскажете "правильный" полифилл?
Гугл выдает много всего, в т.ч. разные самописные. Есть какой-то стандарт де факто?

Вот этот https://github.com/stefanpenner/es6-promise правильный?

Последний раз редактировалось SergeyERjs, 12.07.2017 в 12:17.
Ответить с цитированием
  #6 (permalink)  
Старый 12.07.2017, 13:49
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

https://github.com/petkaantonov/bluebird вроде самый быстрый. Петька Антонов (автор) повёрнут на быстродействии )
Ответить с цитированием
  #7 (permalink)  
Старый 12.07.2017, 14:32
Интересующийся
Отправить личное сообщение для SergeyERjs Посмотреть профиль Найти все сообщения от SergeyERjs
 
Регистрация: 03.07.2017
Сообщений: 19

Alexandroppolus,
Спасибо, попробую.

Вот этот тоже вроде неплох https://github.com/lahmatiy/es6-promise-polyfill. Реализует только стандартный функционал, просто подключается, весит 2,6кБ.
Ответить с цитированием
  #8 (permalink)  
Старый 12.07.2017, 20:39
Интересующийся
Отправить личное сообщение для SergeyERjs Посмотреть профиль Найти все сообщения от SergeyERjs
 
Регистрация: 03.07.2017
Сообщений: 19

Код, который выполняется после цикла, хочется вынести из функции.
Так будет правильно? Можно ли упростить выделенный фрагмент?
Спасибо.
'use strict'
var obj = {count: 0, maxCount: 5};

function doAnything() {
	return new Promise(function(resolve, reject) {
		setTimeout(function () {
			obj.count++;
			console.log("doAnything", obj.count);
			var testError = false;
			if (testError && obj.count==3) {
				console.log("doAnything Error!");
				reject(new Error("err!"));
			}
			resolve(obj);
		}, 500)
	})
}

function isNeedContinue(obj) {
	console.log("isNeedContinue", obj, obj.count <  obj.maxCount);
	return obj.count <  obj.maxCount
}

*!*
(new Promise(function (resolve, reject) {
	(function _repeat() {
		if (isNeedContinue(obj)) {
			doAnything().then(
				function () {
					console.log("Что-то в цикле...");
					_repeat();
				}, function (error) {
					console.log("Ошибка!");
					reject(error);
				})
		} else {
			console.log("Конец цикла");
			resolve(obj);
		}
	})()
}))
*/!*
	.then(function (res) {
		console.log("Что-то после цикла...", res);
	})
	.catch(function (err) {
		console.log("Fail", err);
		throw err;
	});
Ответить с цитированием
  #9 (permalink)  
Старый 13.07.2017, 00:55
Интересующийся
Отправить личное сообщение для SergeyERjs Посмотреть профиль Найти все сообщения от SergeyERjs
 
Регистрация: 03.07.2017
Сообщений: 19

Вынес while в отдельную функцию.
Есть какие-нибудь противопоказания?
Основной код читаемый получился?
'use strict'
var obj = {count: 0, maxCount: 5};

function isNeedContinue(obj) {
	console.log("isNeedContinue", obj, obj.count <  obj.maxCount);
	return obj.count <  obj.maxCount
}

function doAnything() {
	return new Promise(function(resolve, reject) {
		setTimeout(function() {
			obj.count++;
			console.log("doAnything", obj.count);
			var testError = false;
			if (testError && obj.count==3) {
				console.log("doAnything Error!");
				reject(new Error("err!"));
			}
			resolve(obj);
		}, 500)
	})
}

function whilePromise(condition, promise) {
	return new Promise(function(resolve, reject) {
		var _lastResult;
		(function _nextIteration() {
			if (condition()) {
				//console.log("whilePromise. Next iteration.");
				promise().then(function(result) {
					_lastResult = result;
					_nextIteration();
				}, reject);
			} else {
				//console.log("whilePromise. End");
				resolve(_lastResult);
				_lastResult = null;
			}
		})()
	})
}

// Основной код
whilePromise(
	isNeedContinue.bind(null, obj),
	function() {
		return doAnything()
			.then(function() {
				console.log("Что-то еще в цикле...");
				return Promise.resolve(obj);
			}, Promise.reject.bind(Promise))
	}
)
	.then(function(res) {
		console.log("Что-то после цикла...", res);
	})
	.catch(function(err) {
		console.log("Fail");
		throw err;
	});
Ответить с цитированием
  #10 (permalink)  
Старый 13.07.2017, 09:59
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Сообщение от SergeyERjs
Рекурсия промисов.
Прозвучит странно, но я бы не называл это рекурсией. Скорее просто отложенный вызов функции самой себя (привет асинхронность).

У рекурсии есть прямой и обратный ход, глубина.

Сейчас специльно погуглил определении рекурсии, и там прямо так и написано, что рекурсия -- это вызов функции (процедуры) самой себя.
Что ж, могу добавить -- "видимо, только в контексте синхронного исполнения".
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Правильно сделать универсальное условие по выбору и снятию чекбоксов? olegalimov Events/DOM/Window 9 13.06.2017 09:31
не могу открыжить все чекбоксы нажатием одного nenastiy Events/DOM/Window 11 23.05.2010 17:50
Как правильно прописать свой код в .js Всеми_Любимый Элементы интерфейса 6 23.02.2010 21:34
Как правильно послать XML в POST запросе LowCoder AJAX и COMET 10 15.07.2009 23:20
глюк форума Gvozd Сайт Javascript.ru 11 18.03.2009 14:37