My node project currently contains a side Christmas tree of nested callbacks to receive the data and process it in the correct order. Now I'm trying to use refactoring using Promises, but I'm not sure how to do it right.
Say I am compiling a list of offices, then for each office all of their employees, and then the salary of each employee. In the end, all organizations (offices, employees and salaries) must be connected to each other and stored in a database.
Some pseudo codes illustrating my current code (processing error omitted):
fetch(officesEndpoint, function (data, response) { parse(data, function (err, offices) { offices.forEach(function (office) { save(office); fetch(employeesEndPoint, function (data, response) { parse(data, function (err, employees) {
I tried to solve this with Promises, but I have a couple of problems:
- kind of details?
- each office should be associated with their respective employees, but in the
saveEmployees function, I only have access to employees, and not to the office further from the network:
var restClient = require('node-rest-client'); var client = new restClient.Client(); var xml2js = require('xml2js'); // some imaginary endpoints var officesEndpoint = 'http://api/offices'; var employeesEndpoint = 'http://api/offices/employees'; var salaryEndpoint = 'http://api/employees/:id/salary'; function fetch (url) { return new Promise(function (resolve, reject) { client.get(url, function (data, response) { if (response.statusCode !== 200) { reject(statusCode); } resolve(data); }); }); } function parse (data) { return new Promise(function (resolve, reject) { xml2js.parseString(data, function (err, result) { if (err) { reject(err); } resolve(result); }); }); } function saveOffices (offices) { var saveOffice = function (office) { return new Promise(function (resolve, reject) { setTimeout(function () { // simulating async save() console.log('saved office in mongodb'); resolve(office); }, 500); }) } return Promise.all(offices.map(saveOffice)); } function saveEmployees (employees) { var saveEmployee = function (employee) { return new Promise(function (resolve, reject) { setTimeout(function () { // simulating async save() console.log('saved employee in mongodb'); resolve(office); }, 500); }) } return Promise.all(offices.map(saveEmployee)); } fetch(officesEndpoint) .then(parse) .then(saveOffices) .then(function (savedOffices) { console.log('all offices saved!', savedOffices); return savedOffices; }) .then(function (savedOffices) { fetch(employeesEndPoint) .then(parse) .then(saveEmployees) .then(function (savedEmployees) { // repeat the chain for fetching salaries? }) }) .catch(function (error) { console.log('something went wrong:', error); });
user5510778
source share