2017-12-18 11 views
0

현재 API에 대한 약간의 어려움이 있습니다. D API가 내 앱에 필요한 모든 정보를 반환하지 않으며 이는 여러 번 호출해야 함을 의미합니다. 필요한 모든 정보를 얻으십시오. 더구나, 나는 그것의 둘레에 나의 머리를 지키기 위하여 고투하고있다 그래서 잘 설명되지 않는 경우에 저를 알게하십시오! 문제HTTP 통화가 동기화되지 않는 채각/이오 릭 체인 연결

현재 API 흐름의

홈페이지 자세한 사항은 조금 다음과 같습니다

  1. 이 (응답 1 참조) '그룹 ID의'의 목록을 가져옵니다.

  2. 해당 목록을 사용하여 각 그룹 ID에 대해 그룹 세부 정보 및 유형을 가져옵니다 (응답 2 참조).

  3. 그룹 세부 정보를 사용하여 각 유형에 대해 유형 이름을 가져옵니다 (응답 3 참조).

  4. 모든 세부 사항으로 큰 나무를 만듭니다.

  5. 별도의 끝점을 사용하여 모든 '기술'을 얻고 그에 따라 트리를 업데이트하십시오 (응답 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 제공 업체 - getSkillGroups() - [...을 (를) 반환합니다.] 그룹 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) - 반환 {...} 그룹 세부의 응답이 참조 :

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 (

{ 
    "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 
    ] 
} 

응답이 (반환 그룹 세부 정보 : 그룹 ID의 목록) 그룹 및 유형) :

{ 
    "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" 
    ] 
    } 
} 
+0

몇 가지 팁 : 엔드 포인트에서 얻을 수있는 응답과 일치하는 인터페이스 정의를 추가하십시오. 이전 인터페이스를 기반으로 얻을 최종 결과를 정의하는 인터페이스를 추가하십시오. 공급자/서비스 메서드에 명시 매개 변수 및 반환 형식을 추가합니다. 나는 아직도 ppl이 가장 중요한 특징없이 타이프 스크립트를 사용하는 이유를 이해하지 못한다 ... –

답변

0

사용을해야한다 Observables는 추위에 빠지기 때문에 추론 할 수 있고, 배열에 저장할 수 있으며, 결과는 HTTP 요청이 동시에 발생하여 필요한 모든 정보를 수집합니다. 여기

이며, 문제를 해결, 피 감시 체인 (나는 당신이 가지고있는 전체 구현을 복사하지 않습니다로) 의사 코드에서 : 당신이 getSkillGroups()를 호출하면

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); 
} 

, 당신은 response2의 배열을 얻을 형식화 된 데이터입니다. 즉, 새 map 연산자를 추가하여 Observable 배열을 만들어 기술에 세부 정보를 추가 할 수 있습니다. 그럼 당신은 그것에 가입 할 수 있고 당신은 기술을 얻습니다.

Observable을 사용하면 Observable이 더 많은 작업을 수행하고 do 연산자를 사용하여 데이터를 변경하지 않고도 쉽게 디버깅 할 수 있으므로이 옵션과 같이 큰 케이스에는 약속 대신 Observables를 사용하는 것이 좋습니다.

자세한 내용은 rxjs officiel documentation website입니다.

+0

나는 항상 .map 부분에 의해 완전히 잃어 버렸는가? 당신은 그것이하는 것과 왜 다른 것인가를 설명 할 수 있습니까? –

+0

주요 부분은 '지도'가 관찰 가능을 유발하지 않는다는 것이다. 실제로는 (약속을 만들어 내면 약속을 촉발시킨다). 기본적으로지도 연산자는 입력 값을 다른 값으로 변환합니다 (실수를 저질렀습니다. switchMap이어야 함). 그래서지도는 "이전 연산자에서 반환 된 값을 사용하여 이것을 반환합니다". switchMap은 "반환 값을 사용하여 Observable의 결과를 반환하는 것"과 비슷합니다. 이 스키마를 확인하십시오. http://reactivex.io/documentation/operators/map.html지도를 이해하는 데 크게 도움이됩니다. – Supamiu

+0

이제 완전히 잃어 버렸습니다. D 그렇다면 이것을 수신하려면 어떻게 구독 하시겠습니까? –