I'm trying to build an MVC like controller in TypeScript and I'm having difficulty getting my async method to return a deferred promise.
Here's my function signature:
static async GetMatches(input: string, loc?: LatLng):JQueryPromise<any> {
The piler tells me that a 'JQueryPromise' is not a valid async function return type.
I would have thought that something like this would be the most mon use case for an async function but I can't find any examples.
Any help?
I'm trying to build an MVC like controller in TypeScript and I'm having difficulty getting my async method to return a deferred promise.
Here's my function signature:
static async GetMatches(input: string, loc?: LatLng):JQueryPromise<any> {
The piler tells me that a 'JQueryPromise' is not a valid async function return type.
I would have thought that something like this would be the most mon use case for an async function but I can't find any examples.
Any help?
Share Improve this question edited Mar 8, 2016 at 17:34 Bergi 666k161 gold badges1k silver badges1.5k bronze badges asked Mar 8, 2016 at 17:08 Craig PooleCraig Poole 7509 silver badges20 bronze badges 2- Is this still applicable to jQuery 3 (from what I've read it's supposed to be Promises/A+ pliant)? – rink.attendant.6 Commented Feb 5, 2018 at 7:54
- I don't know I'm afraid. I stopped using jQuery not long after this post. I just found it easier to code in vanilla js / typescript instead – Craig Poole Commented Feb 8, 2018 at 14:33
3 Answers
Reset to default 3From the issue detailing async
functions (I found no better reference):
An Async Function must provide a return type annotation that points to a patible
Promise
type. Return type inference can only be used if there is a globally defined, patiblePromise
type.
and then
Async Functions require a patible Promise abstraction to operate properly. A patible implementation implements the following interfaces, which are to be added to the core library declarations (lib.d.ts):
interface IPromiseConstructor<T> { new (init: (resolve: (value: T | IPromise<T>) => void, reject: (reason: any) => void) => void): IPromise<T>; } interface IPromise<T> { then<TResult>(onfulfilled: (value: T) => TResult | IPromise<TResult>, onrejected: (reason: any) => TResult | IPromise<TResult>): IPromise<TResult>; }
jQuery deferreds are - for good reasons - not on their patibility list.
JQueryPromise does not satisfy the requirements for the promises made by async/await, they should inplement the following interfaces:
interface IPromiseConstructor<T> {
new (init: (resolve: (value: T | IPromise<T>) => void, reject: (reason: any) => void) => void): IPromise<T>;
}
interface IPromise<T> {
then<TResult>(onfulfilled: (value: T) => TResult | IPromise<TResult>, onrejected: (reason: any) => TResult | IPromise<TResult>): IPromise<TResult>;
}
For more details see section 4 Promise here: link
To enable async/await for jQuery promises, use the following. It works in bination with jquery.d.ts from DefinitelyTyped.
class JQueryPromise<T> {
constructor(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) {
let dfd = $.Deferred<T>();
function fulfilled(value?: T | PromiseLike<T>) {
let promise = <PromiseLike<T>>value;
if (value && promise.then) {
promise.then(fulfilled, rejected);
}
else {
dfd.resolve(<T>value);
}
}
function rejected(reason) {
let promise = <PromiseLike<T>>reason;
if (reason && promise.then) {
promise.then(fulfilled, rejected);
}
else {
dfd.reject(<T>reason);
}
}
executor(fulfilled, rejected);
return dfd.promise();
}
}
Example:
interface IData {
value: number;
}
async function getValue(): JQueryPromise<number> {
let result = <IData> await $.getJSON('/data.json');
return result.value;
}