Как я могу выполнить динамическим цепочки в Javascript Обещания, все время я видел только жестко прописывать из призывов, например., (promise).then(request/functionName).then(request/functionName)
Dynamic Chaining в Javascript Обещания
ответ
Одним из вариантов является использование свойств объектов и возможность их вызова через строки.
Я написал небольшой образец Here и разместил его ниже.
Идея заключается в том, что у вас есть набор функций, которые вы хотите запустить набор в некотором пространстве имен или объект, как я сделал в «myNamespace»:
myNamespace = {
"A": function() {return "A Function";},
"B": function() {return "B Function";},
"C": function() {return "C Function";}
}
Тогда ваш главный посыл будет работать и как-то (через входы, ajax, подсказки и т. д.) вы получите строковое значение функции, которую вы хотите запустить, которая неизвестна до времени выполнения:
Мое основное обещание использует приглашение получить письмо от пользователя :
var answer = prompt('Starting. Please pick a letter: A,B,C');
if(myNamespace[answer] === undefined)
{
alert("Invalid choice!");
reject("Invalid choice of: " + answer);
}
else
{
resolve(answer);
}
В следующем «затем» Я использую это значение (передается через функцию Resolve) для вызова функции:
.then(function(response) {
funcToRun = myNamespace[response]();})
Наконец, выхода я HTML результата моего вызова динамической функции, и я использую некоторое рекурсивное удовольствие чтобы сделать его более интерактивным и продемонстрировать, что она динамична:
.then(function(){
document.getElementById('result').innerHTML = funcToRun;})
.then(function(){
if(prompt("Run Again? (YES/NO)")==="YES")
{
doWork();
}
});
myNamespace = {
"A": function() {return "A Function";},
"B": function() {return "B Function";},
"C": function() {return "C Function";}
}
function doWork()
{
var funcToRun;
new Promise(function(resolve,reject) {
var answer = prompt('Starting. Please pick a letter: A,B,C');
if(myNamespace[answer] === undefined)
{
alert("Invalid choice!");
reject("Invalid choice of: " + answer);
}
else
{
resolve(answer);
}
})
.then(function(response) {
funcToRun = myNamespace[response]();})
.then(function(){
document.getElementById('result').innerHTML = funcToRun;})
.then(function(){
if(prompt("Run Again? (YES/NO)")==="YES")
{
doWork();
}
});
}
doWork();
<div id="result"></div>
Спасибо Джейсону ... Я постараюсь выполнить то же самое и сообщить вам –
Привет, Джейсон. ... Быстрый вопрос .... Я получаю много запросов (fns, которые вызывают) от действий пользователя. Как проверить текущий статус обещания, а затем цепочку, если он все еще находится в ожидании или просто запускается напрямую, если статус разрешен –
@RamuAjay так, есть значение состояния Promise, но оно личное. Я предполагаю использовать '.done (function() {isPromiseDone = true;})' или какую-то внешнюю переменную, чтобы удерживать текущее состояние обещания. Что касается добавления дополнительных «thens», вы могли бы провести массив функций, а в функции '.done()' вы могли бы проверить этот массив и добавить больше «thens» к обещанию ... это только предположение. – JasonWilczak
Поскольку обещания UnWrap, просто продолжать добавлять then
заявления и он по-прежнему будет прикован вместе
function asyncSeries(fns) {
return fns.reduce(function(p, fn) {
return p.then(fn);
}, Promise.resolve());
}
Рекурсивный довольно прохладный способ сделать это, как хорошо :)
function countTo(n, sleepTime) {
return _count(1);
function _count(current) {
if (current > n) {
return Promise.resolve();
}
return new Promise(function(resolve, reject) {
console.info(current);
setTimeout(function() {
resolve(_count(current + 1));
}, sleepTime);
});
}
}
Спасибо, Трэвис ...... выполнит все предложения –
Привет Трэвис .... Быстрый вопрос .... Я получаю много запросов (fns, которые будут называться) от действий пользователя, Как я могу проверить текущее обещание статус, а затем привязать его к нему, если он все еще ожидает или просто запустит следующую функцию напрямую, если состояние обещания будет разрешено (разрешено или отклонено). - –
Учитывая функции массива, который все возвращающие обещания, вы можете использовать reduce()
запускать их последовательно:
var myAsyncFuncs = [
function (val) {return Promise.resolve(val + 1);},
function (val) {return Promise.resolve(val + 2);},
function (val) {return Promise.resolve(val + 3);},
];
myAsyncFuncs.reduce(function (prev, curr) {
return prev.then(curr);
}, Promise.resolve(1))
.then(function (result) {
console.log('RESULT is ' + result); // prints "RESULT is 7"
});
В приведенном выше примере используется ES6 Promises но все библиотеки обещают имеют сходные черты.
Кроме того, создание массива функций возврата обещаний обычно является хорошим кандидатом для использования map()
.Например:
myNewOrmModels.map(function (model) {
return model.save.bind(model);
}).reduce(function (prev, curr) {
return prev.then(curr);
}, Promise.resolve())
.then(function (result) {
console.log('DONE saving');
});
Хорошая работа с использованием 'reduce' –
Это самый оптовый ответ – user2954463
Любые мысли о том, как избежать потери памяти, вызванной' reduce'? –
Это решение основано на обещаниях использования введенных в ECMAScript 6 (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise), поэтому перед использованием его видеть поддержки таблиц browser`s https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise#Browser_compatibility
Код
var f1 = function(){
for (var i = 0; i < 800000000; i++) {}
console.log('Function1 is done');
}
var f2 = function(){
for (var i = 0; i < 800000000; i++) {}
console.log('Function2 is done');
}
var f3 = function(){
for (var i = 0; i < 800000000; i++) {}
console.log('Function3 is done');
}
var f4 = function(){
for (var i = 0; i < 800000000; i++) {}
console.log('Function4 is done');
}
callbacks = function(){
// copy passed arguments
var callbacks = arguments;
// create array functions
var callbacks = Object.keys(callbacks).map(function(el){ return callbacks[el] });
var now = Date.now();
callbacks.reduce(function(previousPromise, currentFunc){
return previousPromise.then(
function(){
currentFunc();
var seconds = (Date.now() - now)/1000;
console.log('Gone', seconds, 'seconds');
}
)
}, Promise.resolve());
}
callbacks(f1, f2, f3, f4);
Результат в консоли Chrome (значения секунд будут разными):
Function1 is done
Gone 1.147 seconds
Function2 is done
Gone 2.249 seconds
Function3 is done
Gone 3.35 seconds
Function4 is done
Gone 4.47 seconds
Примечания:
- Это не работает, если функция содержит таймер (для этой проблемы я стараюсь также jQuery`s $ Callbacks, $ .ajax и $ .При, но это не помогает. Единственное решение, что я нашел, использование resolve() в обратном вызове таймера , но это неприемлемо, если вы выполнили функции.).
- Тестирование среды
$ google-chrome --version
Google Chrome 53.0.2785.116
Это ES7 путь.
Предположим, у вас есть несколько обещаний, определенных в массиве.
var funcs = [
_ => new Promise(res => setTimeout(_ => res("1"), 1000)),
_ => new Promise(res => setTimeout(_ => res("2"), 1000))
}
И вы хотите позвонить вот так.
chainPromises(funcs).then(result => console.log(result));
Вы можете использовать async
и await
для этой цели.
async function chainPromises(promises) {
for (let promise of promises) { // must be for (.. of ..)
await promise();
}
}
Это будет выполнять указанные функции последовательно (один за другим), а не параллельно. Параметр promises
представляет собой массив функций, которые возвращают Promise
.
я просто была проблема с моим апи провайдера, который делает Promise.all() будет в конечном итоге в задачах параллелизм дб ..
Сделка с моей ситуации является то, что мне нужно получить результат каждого обещания, чтобы показать предупреждение «все нормально» или «кто-то получил ошибку».
И я не знаю, почему .. этот маленький кусочек кода, который использует уменьшить, когда обещания решить я не мог получить мой возможности для работы (слишком поздно, чтобы расследовать сейчас)
$scope.processArray = function(array) {
var results = [];
return array.reduce(function(p, i) {
return p.then(function() {
return i.then(function(data) {
results.push(data);
return results;
})
});
}, Promise.resolve());
}
Так что спасибо к этому сообщению http://hellote.com/dynamic-promise-chains/ Я пришел с этим маленьким ублюдком. Это не полировка, но все работает нормально.
$scope.recurse = function(promises, promisesLength, results) {
if (promisesLength === 1) {
return promises[0].then(function(data){
results.push(data);
return results;
});
}
return promises[promisesLength-1].then(function(data) {
results.push(data);
return $scope.recurse(promises, promisesLength - 1, results);
});
}
Тогда я вызвать функцию следующим образом:
var recurseFunction = $scope.recurse(promises, promises.length, results);
recurseFunction.then(function (response) { ... });
Я надеюсь, что это помогает.
Проверьте следующее учебное пособие для
- программного (динамического) увязывания JavaScript/node.js обещания и
- Promise СЦЕПЛЕНИЯ с помощью рекурсивных функций
Programmatic-Chaining-and-Recursive-Functions-with-JavaScript-Promise
- 1. Chaining ES6 Обещания в Мангусте с машинописью
- 2. JavaScript Chaining Обещание: Вызов следующего обещания, прежде чем предыдущий закончило
- 3. JavaScript/jQuery Promise chaining
- 4. Javascript promation chaining
- 5. Javascript Promise Chaining Issues (Ember)
- 6. javascript ES6 динамически связывающие обещания
- 7. Javascript Window.Onload Function Chaining
- 8. chaining javascript функции
- 9. function chaining in javascript
- 10. Понимание Javascript Chaining Patterns
- 11. Promise chaining (angular javascript)
- 12. Javascript event chaining/binding
- 13. JavaScript: Promise chaining in foreach loop
- 14. JavaScript-обещания: цепочка путаницы обещания
- 15. Q - Chaining Синхронизировать Обещания для обработки успеха и неудачи
- 16. Сухие обещания в javascript
- 17. Парсы JavaScript-обещания в Loop not Completing
- 18. Chaining JavaScript объект (ES6) Proxy
- 19. свойства ember и javascript chaining
- 20. javascript 'this' code for chaining
- 21. JS ES6 Promise Chaining
- 22. RXJS5 chaining like Promises
- 23. Javascript в Dynamic PDF
- 24. Mongoose - chaining promises
- 25. Javascript Обещания в Для Loops
- 26. Сложность обработки Обещания в javascript
- 27. Множественные обещания, связанные в Javascript
- 28. Как работают обещания в JavaScript?
- 29. Javascript - Обещания остаются в ожидании
- 30. понимание объекта обещания javascript
Dynamic - где они исходят? В чем проблема, которую вы пытаетесь решить? Конечно, вы можете передавать любые обратные вызовы, которые вам нравятся, но выбранные, а не только жестко выраженные выражения функций. – Bergi
Поблагодарите Bergi за ответ, они исходят от действий пользователя/событий, таких как щелчки на кнопках и т. Д., –
Вы имеете в виду «var prom = ...; button.onclick = function (e) {prom.then (doSomething); }; '? Конечно, вы можете это сделать, да. Ты это пробовал? – Bergi