Tableau JS API provides multitude of options for interacting, fetching and reusing data from your viz. Mostly, for performance reasons, part of the calls are made in async manner.
Asynchronous part of the Tableau JS API is delivered using Promises methodology. For experienced JavaScript developer is not a big deal, but for the rookies can be a mind-bender. Let’s see have we can handle Promises response with Tableau JavaScript and take benefit from async calls.

According to Tableau JS API documentation Promise returns an Array so it can be easily iterated.

Use Case

Let’s consider simple example. I have 2 filters on dashboard: Order Data and Country. I am interested in getting current values of those filters and displaying it below the graph. Easiest way to do this is use Tableau JavaScript function – getFiltersAsync() which will provide list of filters so I can fetch their values. However, running simple code like this:

var viz;

function initViz() {
 var containerDiv = document.getElementById("vizContainer"),
 
 url="http://dashboard_URL/",
 options = {
 hideTabs: true
 };
 
 viz = new tableau.Viz(containerDiv, url, options);
}


function filtersearch2(i){
	workbook = viz.getWorkbook();
	sheet=viz.getWorkbook().getActiveSheet();
	worksheetArray = sheet.getWorksheets();

	var filtersArray=[];
	var d=$.Deferred();

	(function runner(i){ //note that this is an self-invoking function. you don't have to call it

		worksheetArray[i].getFiltersAsync().then(
		function(filtersArrayReturnedInPromise){

		for (z=0;z<filtersArrayReturnedInPromise.length;z++){
			field = filtersArrayReturnedInPromise[z].getFieldName();

			if (field.search("AutoFilter")>0 && field.search("Action")==-1 ){
				filtersArray[filtersArray.length]=field; //add found filter to the temp array
			}

		// console.log(field);
		}

		if (i==worksheetArray.length-1){
			var uniq = filtersArray.reduce(function(a,b){
			if (a.indexOf(b) < 0 ) a.push(b);
			return a;
		        },[]);

		console.log("resolving filtersearch");
		d.resolve(uniq);

		} else {

			i++;
			runner(i);
		}

		});

	})(i)

return d.promise();
}

will most likely return 1 random filter to the filtersArray and proceed with next code..  Now the issue is clear – Tableau Javascript code proceeds with next operations without waiting for the asynchronous operation to finish

Solution

To make sure that script waits for all filters to be listed, we need to wrap filtersearch() function in .then() callback provided by Tableau API. Code inside .then() callback is performed when operations in the previous function complete.

$(document).ready(function(){
	filtersearch2(0).then(function(filter_found){
//do some other stuff afterwords
});
});

Note that filtername in the function wrapped in .then() holds the object returned from the filterseach() function. This way we can still benefit from the data returned from the first function but after all async operations are finished.

Please feel free to comment below.