11.07.2017, 13:23
|
Интересующийся
|
|
Регистрация: 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.
|
|
11.07.2017, 16:58
|
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 1,012
|
|
дефереды безнадежно устарели. Забудь о них.
лучше юзать нативные промисы. https://jsfiddle.net/jgk0v70f/
|
|
11.07.2017, 17:09
|
Интересующийся
|
|
Регистрация: 03.07.2017
Сообщений: 19
|
|
Цитата:
|
лучше юзать нативные промисы
|
В IE не работает, а это критично. На babel переходить пока не готов.
За пример спасибо.
|
|
11.07.2017, 18:25
|
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 1,012
|
|
Сообщение от SergeyERjs
|
В IE не работает, а это критично.
|
полифилл же есть.
добавь полифилл, и всё заработает. не нужен тут никакой бабель (к счастью).
|
|
12.07.2017, 12:09
|
Интересующийся
|
|
Регистрация: 03.07.2017
Сообщений: 19
|
|
Alexandroppolus,
а не подскажете "правильный" полифилл?
Гугл выдает много всего, в т.ч. разные самописные. Есть какой-то стандарт де факто?
Вот этот https://github.com/stefanpenner/es6-promise правильный?
Последний раз редактировалось SergeyERjs, 12.07.2017 в 12:17.
|
|
12.07.2017, 14:32
|
Интересующийся
|
|
Регистрация: 03.07.2017
Сообщений: 19
|
|
Alexandroppolus,
Спасибо, попробую.
Вот этот тоже вроде неплох https://github.com/lahmatiy/es6-promise-polyfill. Реализует только стандартный функционал, просто подключается, весит 2,6кБ.
|
|
12.07.2017, 20:39
|
Интересующийся
|
|
Регистрация: 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;
});
|
|
13.07.2017, 00:55
|
Интересующийся
|
|
Регистрация: 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;
});
|
|
13.07.2017, 09:59
|
|
junior
|
|
Регистрация: 29.11.2011
Сообщений: 3,924
|
|
Сообщение от SergeyERjs
|
Рекурсия промисов.
|
Прозвучит странно, но я бы не называл это рекурсией. Скорее просто отложенный вызов функции самой себя (привет асинхронность).
У рекурсии есть прямой и обратный ход, глубина.
Сейчас специльно погуглил определении рекурсии, и там прямо так и написано, что рекурсия -- это вызов функции (процедуры) самой себя.
Что ж, могу добавить -- "видимо, только в контексте синхронного исполнения".
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
|
|
|
|