Chaining Promises同时维护数据(angular js)
Chaining Promises while maintaining data (angular js)
我看到了关于链接承诺的一些问题,但这次有点不同。我正在我的代码中进行http获取请求。第一个调用返回一个数组。对于数组中的每个对象,我需要进行另一个http调用,该调用返回另一个数组,依此类推(这将链接3个级别)。问题是,我需要跟踪每个http调用所使用的数组元素,而我不知道如何使用promise来实现这一点。我还想通过返回一个承诺来结束这条链条。
我在nodejs中编写了我想做的事情的代码,但没有承诺:
var https = require('https');
var fs = require('fs');
function makeRequest(options){
var httpopts = {
host: 'soc.courseoff.com',
path: '/gatech/terms/201601/majors/' + options.p,
method: 'GET'
};
var response = "";
var req = https.request(httpopts, function(res) {
res.on('data', function(d) {
response += d;
});
res.on('end',function(){
options.cb(response,options)
})
});
req.end();
req.on('error', function(e) {
console.error(e);
});
}
var classData = {};
function getCourses(m){
var majors = JSON.parse(m);
majors.forEach(function(maj){
classData[maj] = {};
var options = {
p:maj.ident +'/courses',
cb:getSections,
major:maj
};
makeRequest(options);
});
}
var classCount = 0;
function getSections(c,opts){
var courses = JSON.parse(c);
courses.forEach(function(course){
classCount++;
var options = JSON.parse(JSON.stringify(opts));
options.p += '/'+course.ident+'/sections';
options.course = course
options.cb = buildData
makeRequest(options)
});
}
var sectionCount = 0;
function buildData(r, options){
var major = options.major.ident;
sectionCount++;
if(!classData[major]){
classData[major] = {
name: options.major.name,
classes:{}
};
}
classData[major].classes[options.course.ident] = {
name:options.course.name,
sections:JSON.parse(r)
};
console.log('classCount-sectionCount '+classCount + '---'+sectionCount);
if(classCount === sectionCount){
writeIt();
}
}
makeRequest({
p:'',
cb:getCourses
});
function writeIt(){
fs.writeFileSync('./classData.js', 'module.exports = ' + JSON.stringify(classData));
}
编辑:在跟踪数据的同时,我设法使promise嵌套,但如何返回最终用最终数据对象解析的promise?我的代码:谢谢你的帮助!我已经设法对其进行了编码,以便promise能够工作,我现在唯一的问题是将最终数据作为promise 返回
fact.factory('ClassFactory', ['$http',function ($http) {
var eventData = {};
var promise;
var courseData = [];
var baseURL ='https://soc.courseoff.com/gatech/terms/201601/majors/';
eventData.getClasses = function (event) {
if(!promise){
promise = $http.get(baseURL).then(
function(majors){
Promise.all(majors.data.map(m => $http.get(baseURL + m.ident+'/courses')
.then(
function(courses){
if(!m.courses) m.courses = [];
courses.data.map(c => $http.get(baseURL+ m.ident+'/courses/' +c.ident+'/sections' )
.then(
function(sections){
c.sections = sections.data;
m.courses.push(c);
}
));
courseData.push(m);
}
)));
}
)
}
return promise;
}
return eventData;
}]);
几乎可以肯定的是,每次处理Promise数组时,您都会希望使用Promise.all将您的Promise连接并合并为一个新的Promise。然后,该promise将包含每个调用的结果数组。因此,只要您使用映射和闭包之类的东西来捕获外部级别,嵌套的Promise.alls就可以返回具有所有级别结果的Arrays of Arrays。
var fakeCall = x => Promise.resolve(x||Math.random());
Promise.all([fakeCall(1),fakeCall(2)])
.then(
results => Promise.all(results.map( x => fakeCall(5).then( results2 => [x, results2]) ))
)
.then( x => console.log(x));//-> [[1,5],[2,5]]
第一个调用数组生成一个结果数组,映射到那些具有进行更多调用的函数的结果将返回一个可以与其父对象配对的结果。
以这种方式显式嵌套东西将适用于更深层次,但不会很好看。您可能可以使用Array.reduce创建一个抽象,它可以概括此模式。
您在代码中忘记了一些返回。传递给.then
的函数应该总是返回一些内容。此外,您正在修改majors
,但在不使用它的情况下将其丢弃。当使用promise时,尤其是当它们是复杂和嵌套的时,修改这些promise中包含的任何数据结构都不是一个好主意,除非您确信不会发生任何坏的事情。
我会把它分成几个功能。例如
var baseURL ='https://soc.courseoff.com/gatech/terms/201601/majors/';
function getSections(major, course) {
return $http.get(baseURL+ major.ident+'/courses/' +course.ident+'/sections')
.then(sections => sections.data)
.catch(e => []);
}
function getCourses(major) {
return $http.get(baseURL + major.ident+'/courses')
.then(courses => Promise.all(courses.data.map(course =>
getSections(major, course).then(sections => ({[course.ident]: {name: course.name, sections: sections}})))))
.then(courses => angular.extend({}, ...courses))
.catch(e => ({}));
}
function getClassData() {
return $http.get(baseURL)
.then(majors => Promise.all(majors.data.map(major =>
getCourses(major).then(courses => ({[major.ident]: {name: major.name, classes: courses}})))))
.then(majors => angular.extend({}, ...majors))
.catch(e => ({}));
}
getClassData().then(data => console.log(data));
- Angular JS IE9 Hashbang url rewriting
- 无法在数据endVal中设置值=“”;{{ucount}}”;使用Angular JS的CountUp
- angular.js没有'无法在PhoneGap中处理视图标记
- Angular js-返回一个包含类似
- 如何使用 Angular JS 将数据保存在数据库中
- 将Angular js与taglib结合使用
- Angular JS Filter-通过3个复选框进行筛选
- vaadin:使用自定义布局集成angular js
- angular js密码强度显示问题
- 使用angular.js问题的JavaSpringREST服务
- 将复杂对象从angular js传递到web api,它总是返回404
- entre上的angular js阻止提交
- 根据Angular.JS上一次的内容禁用选择
- 如何在angular js中使用指令.不适用于我的情况,为什么
- 预期响应包含一个对象,但在angular js中得到一个数组错误
- angular.js:13424错误:[ng:areq]参数'fn'不是函数,getObject
- 使用Angular js-量角器e2e测试上传文件
- Angular.js延迟控制器初始化
- 如何在angular.js中动态应用自定义过滤器
- 谷歌地图/Angular JS:地图更新并不总是反映数据,并且可以't删除标记