I have an async function getDataItem
that returns a promise and passes data to another function preparePhysicianSchemaData
which builds a global object physicianDetailsObj
out of the passed data as well as data fetched after calling yet another async function inside it for each row of data it was initially passed.
getDataItem(listID, itemID).then(preparePhysicianSchemaData)
Only after the global object variable physicianDetailsObj
is fully populated, then I need to call another function called buildSEOSchemaBlock()
, whose job is to parse physicianDetailsObj
object and build the final object needed.
I would rather not use setTimeOut to try to time this:
setTimeout(function(){ return getListItem(listID, itemID).then(preparePhysicianSchemaData) }, 10);
setTimeout(function(){ return buildPhysicianSchemaBlock() }, 3000);
How can I chain the last function like this: getDataItem(listID, itemID).then(preparePhysicianSchemaData).then(buildPhysicianSchemaBlock)
ensuring that the last function runs only after the global object variable physicianDetailsObj
is fully populated?
var physicianDetailsObj = {};
function getListItem() {} //returns promise
function preparePhysicianSchemaData(item) {
var tempPhysicianDetailsObj = {};
var currentPhysicianItemId = item.get_id();
tempPhysicianDetailsObj = {
"name" : item.get_item("Title"),
"url" : item.get_item("SEOCanonicalHref").match('href="([^"]+)')[1]
};
var currentItemPhysicianTag= item.get_item("PhysicianItemTag").get_label();
getPhysicianLocationDetailsFromServiceLocations(currentItemPhysicianTag).then(function(slitems) {
console.log(slitems);
var slitemEnum = slitems.getEnumerator();
//first empty the object
Object.keys(physicianDetailsObj).forEach(k => delete physicianDetailsObj[k]);
while (slitemEnum.moveNext()) {
var slitem = slitemEnum.get_current();
physicianDetailsObj[currentPhysicianItemId + '-' + slitem.get_id()] = {
"name": tempPhysicianDetailsObj["name"],
"image": tempPhysicianDetailsObj["image"],
"url": tempPhysicianDetailsObj["url"],
"streetAddress": slitem.get_item("LocationAddress"),
"addressLocality": slitem.get_item("LocationLU_x003A_LocationCity").get_lookupValue()
}
}
});
}
function buildSEOSchemaBlock(){ } //process physicianDetailsObj
getPhysicianLocationDetailsFromServiceLocations
is an async function which is called inside preparePhysicianSchemaData
If preparePhysicianSchemaData
is synchronous then you don't need to await it, just perform the operation after it. Something like this:
getListItem(listID, itemID).then(function() {
preparePhysicianSchemaData();
buildPhysicianSchemaBlock();
});
Or if there are results you need from the Promise, something like:
getListItem(listID, itemID).then(function(result) {
preparePhysicianSchemaData(result);
buildPhysicianSchemaBlock();
});
If it's asynchronous then you can chain the Promises, something like:
getListItem(listID, itemID)
.then(function(result) { return preparePhysicianSchemaData(result); })
.then(function(newResult) { return buildPhysicianSchemaBlock(newResult); });
Basically each call to .then()
passes the result of the previous Promise to the new asynchronous function, returning that function's Promise.