首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >角/离子链接HTTP调用退出同步

角/离子链接HTTP调用退出同步
EN

Stack Overflow用户
提问于 2017-12-18 14:21:27
回答 2查看 774关注 0票数 0

我目前正在使用一个API,这有点麻烦:D该API不返回我的应用程序所需的全部信息,这意味着我必须进行多次调用才能获得所需的全部信息。同时,我也在努力保持头脑清醒,所以如果没有很好的解释,请告诉我!

问题的主要细节

当前的API流看起来有点像这样:

  1. 获取'Group‘s’s的列表(请参见响应1)。
  2. 使用该列表,对于每个组ID,获取组中的组详细信息和类型(请参见响应2)。
  3. 使用组详细信息,对于每个类型,获取类型名称(请参见响应3)。
  4. 用所有的细节建造一棵大树。
  5. 使用一个单独的端点,获取所有的“技能”并相应地更新树(参见响应4)。

当试图在正确的位置返回正确的值时会出现问题,这是不同步的,因为我在异步承诺中的承诺中嵌套承诺:O

https://esi.tech.ccp.is/latest/中可以找到主要的API端点和示例。

我的当前代码看起来有点像下面的代码(我尝试按照函数的调用顺序列出它们)。

问题是,我需要找出以下几点:

  • 已返回组的列表。
  • 对于每个组,都返回了所包含的类型。
  • skillTree对象添加了一个新属性,其格式如下。

技能树目标:

代码语言:javascript
复制
skillTree = {
    "groupName": [
        "skillID": {
            "level": 0;
        },
        "skill2ID": {
            "level": 0;
        },...
    ],
    "group2Name": [
        "skillID" {
            "level": 0;
        },...
    ],...
};

选项卡-技能-all.ts(调用主函数):

代码语言:javascript
复制
        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 Provider - buildSkillTree():

代码语言:javascript
复制
     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() -返回。组ID的响应1:

代码语言:javascript
复制
     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 Provider - getSkillsInGroup(id) -返回组详细信息的{.}参见响应2:

代码语言:javascript
复制
    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):

代码语言:javascript
复制
{
  "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(返回组中的组详细信息和类型):

代码语言:javascript
复制
{
  "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返回类型详细信息):

代码语言:javascript
复制
{
  "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

代码语言:javascript
复制
{
  "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"
    ]
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-18 14:40:58

您应该使用可观察的,因为可观察是冷的,所以您可以创建它们,将它们存储在数组中,然后组合结果,以便同时触发http请求,为您所需的一切收集详细信息。

在伪代码中(因为我不会复制整个实现),下面是解决问题的可观察的链:

代码语言:javascript
复制
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-typed数据数组,这意味着您可以在其中添加一个新的map操作符,创建一个可观察的数组来向技能添加详细信息。然后你可以订阅它,你就可以获得技能。

我强烈建议使用可观察性,而不是对这种大案例的承诺,因为可观察允许您完成更多的事情,并且在不使用do操作符改变数据的情况下可以轻松地进行调试。

关于rxjs当然文档网站的更多细节。

票数 0
EN

Stack Overflow用户

发布于 2018-09-08 22:08:10

我正在寻找某种方法来完成异步调用的序列,并找到了这个男孩的文章。简而言之:使用可观察的类forkJoin方法。

查找名为forkJoin的部分

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47870420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档