2016-11-12 1 views
2

Я относительно новичок в nodejs/typescript/promises, поэтому я не уверен в правильном способе обмена обещаниями.Как вы связываете обещания, но меняете тип с одного на другой?

У меня есть класс-помощник, который вызывает REST api для извлечения геолокации на основе ip. Меня не интересует весь ответ, только поле города. Как правильно вернуть обещание, что при разрешении получает только поле города?

var rest = require("axios"); 
const ENDPOINT = "http://freegeoip.net/json/"; 
@Service() 
export class GeoIp { 
    city(ip: string): Promise<any> { 
     let promise: Promise<any>; 
     let p = rest.get(ENDPOINT + ip); 
     p.then((response) => { 
      promise = Promise.resolve(() => {return response.data["city"]}); 
     }, (error) => { 
      promise = Promise.reject(() => { return error}); 
     }); 
     return Promise.resolve(p).then((data)=>promise); 
    } 
} 

Вот мой тестовый код, который не удается, поскольку полученный объект данных исходного REST объект ответа

import chai = require('chai'); 
import {GeoIp} from "../../server/services/GeoIp"; 
var assert = chai.assert; 

describe("GeoIp service",() => { 
    let geoIp: GeoIp; 
    beforeEach("Initialize service",() => { 
     geoIp = new GeoIp(); 
    }); 

    var IP_VALID = "137.118.222.187"; 
    it(`Check geolocation of ${IP_VALID}`, (done) => { 
     let promise = geoIp.city(IP_VALID); 
     promise.then((data) => { 
      console.log(data); 
      assert.equal(data, "Traphill"); 
      done(); 
     }); 
    }); 
}); 
+0

Как указано в ответах, нет необходимости создавать свои собственные обещания. Действительно, это [anti-pattern] (https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern) – cartant

ответ

2
var rest = require("axios"); 
const ENDPOINT = "http://freegeoip.net/json/"; 
@Service() 
export class GeoIp { 
    city(ip: string): Promise<string> { 
     return rest 
      .get(ENDPOINT + ip) 
      .then((response) => response.data.city); 
    } 
} 

Метод then всегда возвращает другой Promise и мак es Обещает цепочку, способную так.

Похоже, что подпись типа должна быть Promise<string>.

+0

Я думаю, что это был бы лучший ответ, если вы не проглотили ошибку. – cartant

+1

Спасибо, я изменю свой ответ –

+0

Работает отлично. Наконец, лучшее понимание обещаний. Я принял этот ответ из-за дополнительного объяснения и дополнительного обещания . Благодаря! – Pierre

3

var rest = require("axios"); 
 
const ENDPOINT = "http://freegeoip.net/json/"; 
 
@Service() 
 
export class GeoIp { 
 
    city(ip: string): Promise<any> { 
 
     return rest.get(ENDPOINT + ip).then((res) => res.data.city); 
 
    } 
 
}