我的节点项目当前包含一个嵌套的回调圣诞树,以便获取数据并按正确的顺序处理它们.现在我正在尝试使用Promises重构,但我不确定如何正确地执行它.
假设我正在提取办公室列表,然后为每个办公室提供所有员工,然后是每个员工的工资.最后,所有实体(办公室,员工和工资)应链接在一起并存储在数据库中.
一些伪代码说明了我当前的代码(省略了错误处理):
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) {
// link each employee to office
save(office);
save(employee);
employees.forEach(function () {
fetch(salaryEndpoint, function (data, response) {
parse(data, function (err, salaries) {
// link salary to employee
save(employee);
});
});
});
});
});
});
});
});
Run Code Online (Sandbox Code Playgroud)
我尝试用承诺解决这个问题,但我有几个问题:
saveEmployees职能中,我只能访问员工,而不是办公室中的其他办公室: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);
});
Run Code Online (Sandbox Code Playgroud)
您承诺的功能fetch、parse和 都很好。有了这些,您可以重构当前的代码以在适用的情况下使用承诺、链式而不是嵌套式,并省略一堆错误处理样板:saveOfficessaveEmployees
fetch(officesEndpoint)
.then(parse)
.then(function(offices) {
return Promise.all(offices.map(function(office) {
return save(office)
.then(function(){ return fetch(employeesEndPoint); })
.then(parse)
.then(function(employees) {
// link each employee to office
// throw in a Promise.all([save(office), save(employee)]) if needed here
return Promise.all(employees.map(function(employee) {
return fetch(salaryEndpoint)
.then(parse)
.then(function(salaries) {
return Promise.all(salaries.map(function(salary) {
// link salary to employee
return save(employee);
}));
});
}));
});
}));
});
Run Code Online (Sandbox Code Playgroud)
在最里面的循环回调中,您已经获得了所有office,employee并salary可以根据您的喜好将它们相互链接。你无法真正避免这种嵌套。
您将收到大量保存结果数组或整个过程中任何错误的承诺。
| 归档时间: |
|
| 查看次数: |
196 次 |
| 最近记录: |