角度/离子链接HTTP呼叫不同步
我目前正在使用一个有点痛苦的API:D API不会返回我的应用程序所需的全部信息,这意味着我必须多次调用得到所需要的全部信息。另外,我努力保持我的头一轮就那么如果它不能很好地解释只是让我知道!角度/离子链接HTTP呼叫不同步
问题
目前API流的主要细节看起来有点像这样:
获取 '群组的ID' 的列表(见反应1)。
使用该列表,对于每个组ID,获取组中的组详细信息和类型(请参见响应2)。
使用组详细信息,为每种类型获取类型名称(请参见响应3)。
建立一个大的树的所有细节。
使用单独的终点,获取所有“技能”并相应地更新树(请参见响应4)。
这个问题是试图在正确的位置是所有不同步返回正确的值时,因为我嵌套承诺在异步承诺承诺:o
主要API端点和示例可以在https://esi.tech.ccp.is/latest/找到。
我目前的代码看起来有点像下面(我尝试按顺序列出函数)。
的问题是,我需要找到一点:
组的名单已返回。
对于每个组类型包括已退回。
skillTree对象已经添加了一个新的属性,这是在下面的格式。
技能树目的:
skillTree = { "groupName": [
"skillID": {
"level": 0;
},
"skill2ID": {
"level": 0;
},...
],
"group2Name": [
"skillID" {
"level": 0;
},...
],...
};
制表技能all.ts(调用主要功能):
eveESI.buildSkillTree().then(() => { // Need to add names to all skills in tree...
console.log('Completed skill tree:');
console.log(eveESI.skillTree);
}).catch((error) => {
// Do error handling...
});
eveESI提供商 - buildSkillTree():
buildSkillTree(){ return new Promise((resolve, reject) => {
this.getSkillGroups().then((groups) => {
console.log('Success: Fetched groups successfully!');
console.log(groups);
// Process groups. First get group details including types. Then for each group push to main array.
for (var i in groups) {
if (groups.hasOwnProperty(i)) {
this.getSkillsInGroup(groups[i]).then((data) => {
var groupDetails = JSON.parse(data.toString());
var types = groupDetails.types;
var name = groupDetails.name;
console.log('Success: Fetched types for group ' + name + ' successfully!');
// Declare and build temp group object before we push it to main skill object...
var tempGroupObj = [];
// For each skill type in the group add to temporary array...
for (var n in types) {
if (types.hasOwnProperty(n)) {
tempGroupObj[types[n]] = {};
tempGroupObj[types[n]]['level'] = 0;
}
}
console.log(tempGroupObj);
this.skillTree[name] = tempGroupObj;
}).then(() => {
}).catch((error) => {
// Do error handling...
console.log(error);
});
}
}
resolve();
}).catch((error) => {
// Do error handling...
reject();
});
});
}
eveESI Provider - getSkillGroups() - returns [...]组ID的响应见的1:
getSkillGroups(){ return new Promise((resolve, reject) => {
this.http.get(this.apiRoot + 'universe/categories/16/', { }, { Authorization: 'Basic YWUxYmIzZDU4ZmRiNDk1ZDk3ZTE1ZTE0OTIyZDc0ZDk6MnpsVjNLZzVHbTh4OHY5b2lUSENYOHVXR21PYjlHd2Rqc3htQ0NHOA=='})
.then(reqResponse => {
// Returns {} of skill groups from category...
var responseJSON = JSON.parse(reqResponse.data);
resolve(responseJSON.groups);
}).catch(reqError => {
// Error. Return error message...
reject();
});
});
}
eveESI提供商 - getSkillsInGroup(ID) - 的组的信息返回{...}看到响应2:
getSkillsInGroup(id){ return new Promise((resolve, reject) => {
this.http.get(this.apiRoot + 'universe/groups/' + id + '/', { }, { Authorization: 'Basic YWUxYmIzZDU4ZmRiNDk1ZDk3ZTE1ZTE0OTIyZDc0ZDk6MnpsVjNLZzVHbTh4OHY5b2lUSENYOHVXR21PYjlHd2Rqc3htQ0NHOA=='})
.then(reqResponse => {
resolve(reqResponse.data);
}).catch(reqError => {
// Error. Return error message...
reject();
});
});
}
响应1(列出组ID的):
{ "category_id": 16,
"name": "Skill",
"published": true,
"groups": [
255,
256,
257,
258,
266,
268,
269,
270,
272,
273,
274,
275,
278,
505,
1209,
1210,
1213,
1216,
1217,
1218,
1220,
1240,
1241,
1545
]
}
响应2(返回组细节和组类型):
{ "group_id": 255,
"name": "Gunnery",
"published": true,
"category_id": 16,
"types": [
3300,
3301,
3302,
3303,
3304,
3305,
3306,
3307,
3308,
3309,
3310,
3311,
3312,
3315,
3316,
3317,
11082,
11083,
11084,
12201,
12202,
12203,
12204,
12205,
12206,
12207,
12208,
12209,
12210,
12211,
12212,
12213,
12214,
12215,
20327,
21666,
21667,
22043,
24563,
32856,
41403,
41404,
41405,
41406,
41407,
41408,
41537
]
}
响应3(返回由ID类型的详细信息):
{ "type_id": 3300,
"name": "Gunnery",
"description": "Basic turret operation skill. 2% Bonus to weapon turrets' rate of fire per skill level.",
"published": true,
"group_id": 255,
"market_group_id": 364,
"radius": 1,
"volume": 0.01,
"packaged_volume": 0.01,
"icon_id": 33,
"capacity": 0,
"portion_size": 1,
"mass": 0,
"dogma_attributes": [...],
"dogma_effects": [...]
}
的package.json
{ "name": "name",
"version": "0.0.1",
"author": "author",
"homepage": "http://ionicframework.com/",
"private": true,
"scripts": {
"clean": "ionic-app-scripts clean",
"build": "ionic-app-scripts build",
"lint": "ionic-app-scripts lint",
"ionic:build": "ionic-app-scripts build",
"ionic:serve": "ionic-app-scripts serve"
},
"dependencies": {
"@angular/common": "5.0.3",
"@angular/compiler": "5.0.3",
"@angular/compiler-cli": "5.0.3",
"@angular/core": "5.0.3",
"@angular/forms": "5.0.3",
"@angular/http": "5.0.3",
"@angular/platform-browser": "5.0.3",
"@angular/platform-browser-dynamic": "5.0.3",
"@ionic-native/browser-tab": "^4.4.2",
"@ionic-native/core": "4.4.0",
"@ionic-native/deeplinks": "^4.4.2",
"@ionic-native/http": "^4.4.2",
"@ionic-native/secure-storage": "^4.4.2",
"@ionic-native/spinner-dialog": "^4.4.2",
"@ionic-native/splash-screen": "4.4.0",
"@ionic-native/sqlite": "^4.4.2",
"@ionic-native/sqlite-porter": "^4.5.0",
"@ionic-native/status-bar": "4.4.0",
"@ionic/storage": "^2.1.3",
"angular2-natural-sort": "0.0.2",
"angular2-swagger-client-generator": "0.0.22",
"cordova-android": "6.3.0",
"cordova-plugin-advanced-http": "^1.9.0",
"cordova-plugin-browsertab": "^0.2.0",
"cordova-plugin-compat": "^1.2.0",
"cordova-plugin-device": "^1.1.4",
"cordova-plugin-file": "^5.0.0",
"cordova-plugin-ionic-webview": "^1.1.16",
"cordova-plugin-native-spinner": "^1.1.3",
"cordova-plugin-secure-storage": "^2.6.8",
"cordova-plugin-splashscreen": "^4.0.3",
"cordova-plugin-statusbar": "^2.3.0",
"cordova-plugin-whitelist": "^1.3.1",
"cordova-sqlite-storage": "^2.1.2",
"ionic-angular": "3.9.2",
"ionic-plugin-deeplinks": "^1.0.15",
"ionic-plugin-keyboard": "^2.2.1",
"ionicons": "3.0.0",
"ngx-order-pipe": "^1.1.1",
"rxjs": "5.5.2",
"sw-toolbox": "3.6.0",
"swagger-angular-generator": "^1.2.1",
"uk.co.workingedge.cordova.plugin.sqliteporter": "^1.0.2",
"zone.js": "0.8.18"
},
"devDependencies": {
"@ionic/app-scripts": "3.1.4",
"typescript": "2.4.2"
},
"description": "An Ionic project",
"cordova": {
"plugins": {
"ionic-plugin-keyboard": {},
"cordova-plugin-whitelist": {},
"cordova-plugin-device": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic-webview": {},
"cordova-plugin-browsertab": {},
"ionic-plugin-deeplinks": {
"URL_SCHEME": "_CUSTOMURLSCHEME",
"DEEPLINK_SCHEME": "https",
"DEEPLINK_HOST": "localhost",
"ANDROID_PATH_PREFIX": "/",
"ANDROID_2_PATH_PREFIX": "/",
"ANDROID_3_PATH_PREFIX": "/",
"ANDROID_4_PATH_PREFIX": "/",
"ANDROID_5_PATH_PREFIX": "/",
"DEEPLINK_2_SCHEME": " ",
"DEEPLINK_2_HOST": " ",
"DEEPLINK_3_SCHEME": " ",
"DEEPLINK_3_HOST": " ",
"DEEPLINK_4_SCHEME": " ",
"DEEPLINK_4_HOST": " ",
"DEEPLINK_5_SCHEME": " ",
"DEEPLINK_5_HOST": " "
},
"cordova-plugin-secure-storage": {},
"cordova-plugin-native-spinner": {},
"cordova-plugin-advanced-http": {},
"cordova-sqlite-storage": {},
"cordova-plugin-statusbar": {},
"uk.co.workingedge.cordova.plugin.sqliteporter": {}
},
"platforms": [
"android"
]
}
}
回答:
你应该使用因为Observable是冷的,所以你可以创建它们,将它们存储在一个数组中,然后再合并它们结果,以便您的http请求同时被触发,收集您需要的所有内容的详细信息。
这里,在伪代码(我将不会复制你的整个实现),可观测链解决您的问题:
getSkillGroups() { this.http.get(this.apiRoot + 'universe/categories/16/', {}, {Authorization: 'Basic YWUxYmIzZDU4ZmRiNDk1ZDk3ZTE1ZTE0OTIyZDc0ZDk6MnpsVjNLZzVHbTh4OHY5b2lUSENYOHVXR21PYjlHd2Rqc3htQ0NHOA=='})
.switchMap(response1 => {
const groupsDetails: Observable<any>[] = [];
response1.groups.forEach(group => {
groupsDetails.push(this.getSkillsInGroup(group));
});
//This will return an array of requests ready to be fired right when you call subscribe on it
// When fired, the requests will be parallels, not sync.
return Observable.combineLatest(groupsDetails);
});
}
getSkillsInGroup(id){
return this.http.get(this.apiRoot + 'universe/groups/' + id + '/', { }, { Authorization: 'Basic YWUxYmIzZDU4ZmRiNDk1ZDk3ZTE1ZTE0OTIyZDc0ZDk6MnpsVjNLZzVHbTh4OHY5b2lUSENYOHVXR21PYjlHd2Rqc3htQ0NHOA=='})
.map(response2 => response2.data);
}
一旦你调用getSkillGroups()
,你得到的response2
数组的数据,这意味着你可以添加一个新的map
操作符,创建一个Observable数组来添加细节到技能。然后你可以订阅它,你会得到技能。
我强烈建议使用,而不是承诺的大案像这样的观测量,如可观察到让你做的方式更多的事情,并没有使用do
运营商改变数据方便调试。
有关rxjs officiel documentation website的更多详细信息。
以上是 角度/离子链接HTTP呼叫不同步 的全部内容, 来源链接: utcz.com/qa/264106.html