Thursday, May 23, 2024
63
rated 0 times [  67] [ 4]  / answers: 1 / hits: 17880  / 7 Years ago, tue, july 18, 2017, 12:00:00

I am having trouble writing an asynchronous function using promises



function requestsPlot(plot, info) {
return new Promise(function(resolve, reject) {
var plotObject = fieldsObject[plot]
var sqr = new Promise(function(resolve1, reject) {
debugger;
get(createSQRurl(plotObject.polygon))
.then(function(result) {
plotObject.quality = sqrHtmlParsing(result);
resolve1();
});
});
var soilType = new Promise(function(resolve2, reject) {
get(createSoilTypeUrl(plotObject.polygon))
.then(function(result) {
plotObject.soilType = soilTypeHtmlParsing(result);
resolve2();
});
});
var distance = new Promise(function(resolve3, reject) {
var start = turf.centerOfMass(plotObject.polygon).geometry.coordinates;
var end = info.homeCoords;
get('http://router.project-osrm.org/route/v1/driving/' + start + ';' + end + '?overview=false')
.then(function(result) {
var parsed = JSON.parse(result);
if (parsed.code == 'Ok') {
plotObject.distance = parsed.routes[0].distance / 1000;
resolve3()
} else {
plotObject.distance = '';
resolve3()
}
});
});

Promise.all([sqr, soilType, distance]).then(function() {
resolve('test');
})
})
}


The idea is to resolve the promise returned by the requestPlot function after all promises inside the function (variables sqr, soilType and distance) are resolved. However, the promise is resolved while all requests in the get function are still pending. Note that the 'get' function also returns a promise.
Thanks a lot for your help!



P.S. here's the get function



function get(url) {
var requestPromise = new Promise(function(resolve, reject) {
var req = new XMLHttpRequest();
req.open('get', url);

req.onload = function() {
if (req.status == 200) {
resolve(req.response);
}
else {
reject(Error(req.statusText));
}
};

req.onerror = function() {
reject(Error(Network Error));
};
req.send();
});
return requestPromise
}

More From » ecmascript-6

 Answers
15

Nesting promises within promises is a well-known anti-pattern.



You don't need any of those promise constructors because you already have get which returns a promise and you can just use it directly.



Here's how you can re-write your code:



function requestsPlot(plot, info) {

const sqr = get(createSQRurl(plotObject.polygon))
.then(sqrHtmlParsing);

const soilType = get(createSoilTypeUrl(plotObject.polygon))
.then(soilTypeHtmlParsing);

const start = turf.centerOfMass(plotObject.polygon).geometry.coordinates;
const end = info.homeCoords;
const distance = get('http://router.project-osrm.org/route/v1/driving/' + start + ';' + end + '?overview=false')
.then(JSON.parse);

return Promise.all([sqr, soilType, distance])
.then(([parsedSqr, parsedSoilType, parsedDistance]) =>
Object.assign(plotObject, {
quality: parsedSqr,
soilType: parsedSoilType,
distance: parsedDistance.code == 'Ok'
? parsed.routes[0].distance / 1000
: ''
}))
}

[#57040] Saturday, July 15, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
jack

Total Points: 557
Total Questions: 96
Total Answers: 80

Location: Saint Helena
Member since Mon, Jan 16, 2023
1 Year ago
jack questions
Sun, Jan 31, 21, 00:00, 3 Years ago
Thu, Dec 10, 20, 00:00, 4 Years ago
Sat, Aug 1, 20, 00:00, 4 Years ago
Fri, Apr 17, 20, 00:00, 4 Years ago
Wed, Aug 14, 19, 00:00, 5 Years ago
;