I'll try to make this short.
The code in Example 1 works fine, like it should, but the code in Example 2 does not, and the only difference is that it's started with an ajax call(in this case a dummy one). The call get's the array that will be parsed. But in 'then' function it just goes to the first furthest 'tree' branch and stops. How does 'then' cause this?
It's supposed to be a 'tree like' walk through.
$(function() {
$('button').on('click', function() {
runSequence('list_one').then(function() {
document.getElementById('output').innerHTML += 'Done<br>';
});
});
});
let lists = {
list_one: [{Action: '@ActionOne: argument', ListNo: '1'}, {Action: '@ActionList: list_two', ListNo: '1'}, {Action: '@ActionThree: argument', ListNo: '1'}],
list_two: [{Action: '@ActionOne: argument', ListNo: '2'}, {Action: '@ActionList: list_three', ListNo: '2'}, {Action: '@ActionThree: argument', ListNo: '2'}],
list_three: [{Action: '@ActionOne: argument', ListNo: '3'}, {Action: '@ActionTwo: argument', ListNo: '3'}, {Action: '@ActionThree: argument', ListNo: '3'}],
};
var runSequence = (function(name) {
return initSequence(lists[name]);
});
var initSequence = (function(sequence) {
return sequence.reduce(function(sequence, action) {
let act = action['Action'];
let actName = act.substr(0, act.indexOf(':')).trim();
let actArg = act.substr(act.indexOf(':')+1).trim();
document.getElementById('output').innerHTML += action['ListNo'] + ' - ' + actName + ': ' + actArg + '<br>';
return executeAction(actName, actArg);
}, Promise.resolve());
});
var executeAction = (function(actionName, actionArgument) {
if(actionName == '@ActionList') {
return runSequence(actionArgument);
}
return Promise.resolve();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>start</button>
<div id="output"></div>
$(function() {
$('button').on('click', function() {
runSequence('list_one').then(function() {
document.getElementById('output').innerHTML += 'Done<br>';
});
});
});
let lists = {
list_one: [{Action: '@ActionOne: argument', ListNo: '1'}, {Action: '@ActionList: list_two', ListNo: '1'}, {Action: '@ActionThree: argument', ListNo: '1'}],
list_two: [{Action: '@ActionOne: argument', ListNo: '2'}, {Action: '@ActionList: list_three', ListNo: '2'}, {Action: '@ActionThree: argument', ListNo: '2'}],
list_three: [{Action: '@ActionOne: argument', ListNo: '3'}, {Action: '@ActionTwo: argument', ListNo: '3'}, {Action: '@ActionThree: argument', ListNo: '3'}],
};
var runSequence = (function(name) {
return sendRequest('sequence', 'test').then(function(res) {
return initSequence(lists[name]);
});
});
var initSequence = (function(sequence) {
return sequence.reduce(function(sequence, action) {
let act = action['Action'];
let actName = act.substr(0, act.indexOf(':')).trim();
let actArg = act.substr(act.indexOf(':')+1).trim();
document.getElementById('output').innerHTML += action['ListNo'] + ' - ' + actName + ': ' + actArg + '<br>';
return executeAction(actName, actArg);
}, Promise.resolve());
});
var executeAction = (function(actionName, actionArgument) {
if(actionName == '@ActionList') {
return runSequence(actionArgument);
}
return Promise.resolve();
});
var sendRequest = (function(type, param) {
return $.ajax({
url: '//posttestserver.com/post.php',
method: 'post',
data: JSON.stringify({
type: type,
param: param
})
}).then(function(response, status, xhr) {
return response;
}, function(xhr, status, error) {
return error;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>start</button>
<div id="output"></div>
EDIT (FIX) :
The problem was jQuery 2.x as it was messing up with promises, using jQuery 3.x solved the problem. Also reduce
was not a good idea to use here. Replaced it with each
from Bluebird to make it work like it should.