2015-09-24 1 views
8

Я хотел бы вернуть обещание и объект с именем output до или после вызова $ http. Может кто-нибудь посоветует мне, как я могу это сделать с помощью рамки AngularJS и очень важно с Typcript, поэтому я могу быть уверен, что он работает правильно?Как я могу вернуть успех и обещание об ошибке с данными и без них?

topicNewSubmit =(): ng.IPromise<any> => { 
    var self = this; 
    var myData1 = { abc: 123 } 

    if (self.abc = 22) { 
     // How can I return an OKAY promise from here? 
    } 
    if (self.abc = 33) { 
     // How can I return an OKAY promise with myData1 from here? 
    } 
    if (self.abc = 88) { 
     // How can I return a FAIL promise from here? 
    } 

    return self.$http({ url: self.url, method: "GET" }) 
     .then(
      (response: ng.IHttpPromiseCallbackArg<any>): any => {    
      var myData2 = { abc: 245 } 
      // How can I return a promise and myData2. 
      // return(myData2) gives an error with Typescript 

      // How can I return a promise and no data 
      // return gives an error with Typescript 
     }, 
     (error: ng.IHttpPromiseCallbackArg<any>): ng.IPromise<any> => { 
      var myData3 = { abc: 345 } 
      // Is this the correct way to return an unhandled reject with myData3 
      return self.$q.reject(myData); 
     }); 
    } 
+4

https://docs.angularjs.org/api/ng/service/$q#resolve '$ q' имеет' resolve' метод. Если вы используете более раннюю версию Angular, используйте '.when'. Они делают то же самое. Кроме того, методы $ http' уже возвращают обещания. Вам не нужно использовать внутреннюю цепочку обещаний. –

+0

@ExplosionPills - Если у вас есть несколько минут, вы можете добавить свои комментарии в качестве ответа на мой пример с коротким кодом. Я не совсем уверен, что вы подразумеваете под «$ http methods, которые уже дают обещания. Вам не нужно будет использовать другую цепочку обещаний». Одна вещь, которую я видел из моего тестирования, и причина, по которой я добавил себя. $ Q.reject заключался в том, что если бы я обработал отклонение без возврата туда, то моя темаNewSubmit всегда возвращалась бы хорошо. Надеюсь, это имеет смысл. Большое спасибо. –

+0

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

ответ

4

Редактировать: Исправлен код и добавлен TypeScript Playground example. Методы правильно набраны, вы можете проверить это, набрав ошибки ввода, попытайтесь их исправить;). Я скопировал все основные интерфейсы из файла углового определения.

Редактировать # 2: Here's the fixed version примера, приведенного выше.

Если я правильно понял ваш вопрос, вы пытаетесь определить тип возврата для метода службы, заявляя, что он возвращает обещание, результатом которого при разрешении будет определенный объект?

В этом случае вы почти там, я разделил ваши два примера методов в отдельных блоках, так как они требуют другого подхода.

В общем случае я удалил область копирования (self = this), поскольку вы используете методы толстой стрелки, которые автоматически будут обладать методом внешней лексической области. Короче говоря, нет необходимости делать копию области, и на самом деле, в вашем примере self не всегда указывает на службу (поскольку вы копируете область внутри метода, а не за ее пределами).

Кроме того, обратите внимание на определение углового обещания (усеченного):

interface IDeferred<T> { 
    resolve(value?: T): void; 
    reject(reason?: any): void; 
} 

Как таковые, набрав угловую Promise только добавить типизации для решимости случая обещания, а не для отклоненный случай. Следовательно, при вызове вашей службы он проверяет, что результат в обработчике успеха имеет тип, который вы определили, но тип параметров в обработчике ошибок имеет тип any.

topicTest

Для этого метода для работы нужно вводить $q в вашу службу, а затем использовать его, чтобы создать свой собственный deferred

topicTest =(): IPromise<Foo> => { // return a promise which will result in a parameter of MyType upon resolving 
    var deferred = this.$q.defer<Foo>(); // Type the deferred to get better 'intellisense' support 
    if (this.abc = 99) { 
     deferred.resolve(new Foo()); 
    } 
    if (this.abc = 88) { 
     deferred.reject("You can pass in whatever you like to the reject case"); 
    } 
    return deferred.promise; 
}; 

topicNewSubmit

$http уже возвращает обещания, так вам нужно всего лишь подключить их, установив обратный вызов then и , возвращая из этого метода t o разрешить соединение других then callabacks к нему.

В этом случае возвращаемый тип вашего метода обслуживания будет angular.IPromise<() => any>, где вы можете заменить any на тип, который вам нужен. Возвращаемый тип метода then должен соответствовать любому типу, который вы выбрали для общего заполнителя в возвращаемом типе метода обслуживания.

topicNewSubmit =() : IPromise<Foo> => { 
    return this.$http({ url: this.url, method: "GET" }).then((response): Foo => { 
     return new Foo(); 
    }, (error) => { 
     return "whatever you'd like, it does not have to correspond to Foo"; 
    }); 
} 

Вы могли бы затем использовать сервис как

MyService.topicNewSubmit().then((data) => { 
    // data needs to be of type T, where T is the type you defined in the generic placeholder of IPromise<T> 
}, (error: any) => { 
    // In the error case, the parameters are of type any 
}); 
+0

Спасибо за ваш ответ. В моем возврате вывода IDE в topicNewSubmit отображается как ошибка: Type '{abc: string; } 'не присваивается типу' IPromise '. Также в вашем ответе комментарий «// аналогичная ошибка теперь будет равна {abc:« просто пример »}« не будет достигнута, так как вы обрабатываете ошибку в topicNewSubmit, и поэтому она вернет успех. –

+0

Я не уверен относительно типа возврата, проверит это позже. Но ошибка не обрабатывается в обратном вызове успеха, так что пример будет работать. Метод 'then' принимает два обратных вызова с успехом и ошибку. – thomaux

+0

Привет, Анна, я плохо, я забыл обновить возвращаемый тип обратного вызова ошибки, исправил это в моем редактировании. – thomaux

2

Ответ

Вы не можете вернуть то, что пока не существует, если вы не блокировать все операции, пока вы получите это. Так как браузер JavaScript (в основном) одинарный, вы не хотите блокировать поток, а файл загружается. Следовательно, вы возвращаете обещание, которое в конечном итоге решит проблему. Потребителю необходимо использовать функцию then до , в конце концов получите значение.

Юмор

Обещание на всю жизнь. Его начало вплоть до

+0

Моя проблема в том, что когда я использую: return self. $ Q.resolve (output); он говорит мне, что недействителен и $ q. не имеет решения. –

+0

'$ q. не имеет решения. 'звучит как * старая * версия углового – basarat

+0

Итак, как я могу вернуть данные из успеха вызова $ http? Также возвращается self. $ Q.reject ('Ошибка во время Multi-save'); правильный способ вернуть неудавшееся обещание из блока отказа вызова $ http? –

3

Честно говоря, я чувствую, как я стреляю в темноте с образцом кода, но вот мое решение.

Как Анцео, я удалил ссылки на self или this. $q и $http.

declare var $q: ng.IQService; 
declare var $http: ng.IHttpService; 

var topicNewSubmit =(): ng.IPromise<any> => { 

    var deferred = $q.defer<any>(); 

    var myData1 = { abc: 123 }; 

    if (this.abc = 22) { 

     deferred.resolve(); 

    } else if (this.abc = 33) { 

     deferred.resolve(myData1); 

    } else if (this.abc = 88) { 

     deferred.reject(); 

    } else { 

     $http({ 
      url: this.url, 
      method: "GET" 
     }) 
     .then(() => { 
      deferred.resolve({ abc: 245 }); 
     },() => { 
      deferred.reject({ abc: 345 }); 
     }); 
    } 

    return deferred.promise; 
}; 
2

Вы можете использовать обещание как

var deferred = $q.deferred(); 
    $http(api url and method) 
    .success function() { 
     deferred.resolve(); 
    } 
    .failure function() { 
     deferred.reject(); 
    } 
    return deferred.promise; 
+0

Почему я должен это делать, когда $ http уже возвращает обещание? –

+0

Не согласен. Не нужно возвращать обещание с $ http, так как $ http - это обещание. См. Угловую документацию: https://docs.angularjs.org/api/ng/service/$http -> Общее использование. – ilmgb