JQuery цепочка и каскадирование тогда и когда

В настоящее время у меня есть передо мной замкнутая петля if-then-else, которая сначала получает несколько cantinas из webservice. Затем он получает все доступные блюда (для каждого меню) и все доступные боковые блюда (для каждого меню). Для каждого из блюд, а также сторон, он проверяет все добавки и агрегирует их.

В конце у меня есть несколько меню с едой, гарнирами и всеми их добавками.

Следующая блок-схема показывает процесс:
enter image description here

Я хочу украсить код и хочу использовать promises с jQuery - но я не могу понять, как это сделать, поскольку мне нужно складывать then после when (по крайней мере, я думаю, может быть, мне нужно resolve?). Следующее - моя лучшая попытка:

//this totally does not work at all, but you get the idea what I want to do
Menus.getCantinas()
       .when(Menus.getMeals(cantinas), Menus.getSides(cantinas)) //when doesn't exist here, neither does cantinas
         .then(Menus.getAdditives(meals, sides) //also throws errors as meals and sides does not exist
           .done(function(cantinas, meals, sides, additives) { //more errors for the people
             Menus.cantinas = cantinas;
             Menus.meals = meals;
             Menus.sides = sides;
             Menus.additives = additives;

             //... some html stuff to build the menus
           });

Обязательно ознакомьтесь со следующим фрагментом кода для более подробного кода.

window.Menus = {
	cantinas = {},
	meals = {},
	sides = {},
	additives = {},
	callWebservice: function (listname, filter)
    {
        if (filter && filter != '')
            data['$filter'] = filter;

        return jQuery.ajax({
            url: '/_api/web/lists/getbytitle(\'' + listname + '\')/items',
            data: data,
            dataType: 'json'
        });
    },

	getCantinas: function() {
		return Menus.callWebservice("Cantinas", "");
	},
	
	getMeals: function(cantinas) {
		var filterString;
		for (var i = 0; i < cantinas.length; i++) {
			if (i == 0) {
				filterstring = "ID eq " + cantinas[i];
			}
			else {
				filterstring += " or ID eq " + cantinas[i]
			}
		}
		return Menus.callWebservice("Meals", filterString);
	},
	
	
	getSides: function(cantinas) {
		//see above function for filterstuff
		return Menus.callWebservice("Sides", filterString);
	},
	
	getAdditives: function(meals, sides) {
		for (var i = 0; i < meals.length; i++) {
			if (i == 0 && !meals) {
				filterstring = "ID eq " + meals[i];
			}
			else {
				filterstring += " or ID eq " + meals[i]
			}
		}
		
		for (var i = 0; i < sides.length; i++) {
			if (i == 0 && !sides) {
				filterstring = "ID eq " + sides[i];
			}
			else {
				filterstring += " or ID eq " + sides[i]
			}
		}
		return Menus.callWebservice("Additives", "");
	}
	Init: function() {
		//this totally does not work at all, but you get the idea what I want to do
		Menus.getCantinas()
			   .when(Menus.getMeals(cantinas), Menus.getSides(cantinas))
			     .then(Menus.getAdditives(meals, sides)
			       .done(function(cantinas, meals, sides, additives){
				     Menus.cantinas = cantinas;
					 Menus.meals = meals;
					 Menus.sides = sides;
					 Menus.additives = additives;
					 
					 //... some html stuff to build the menus
				   });
	}
}
Menus.Init()

Ответ 1

Как и комментарии, $.when - свободная функция. Если мы используем then способную цепочку, мы можем получить довольно чистый синтаксис здесь.

Menus.getCantinas().then(function(cantinas){ // `then` is how we chain promises
    Menus.cantinas = cantinas;
    // if we need to aggregate more than one promise, we `$.when`
    return $.when(Menus.getMeals(cantinas), Menus.getSides(cantinas));
}).then(function(meals, sides){ // in jQuery `then` can take multiple arguments
    Menus.sides = sides; // we can fill closure arguments here
    Menus.meals = meals;
    return Menus.getAdditives(meals, sides); // again we chain
}).then(function(additives){
    Menus.additives = additives;
    return Menus; // we can also return non promises and chain on them if we want
}).done(function(){ // done terminates a chain generally.
     // edit HTML here
});