Async code

Topics: General
Oct 1, 2012 at 8:03 PM

One of the biggest pains of writing Asynchronous JS code is not having the "await" keyword and syntax sugar of .NET

I would love to get support of await for promises and functions taking a callback as last argument in TypeScript that would desugar in ".then(...)" or "callAsync(args, ...)". Functions using "await" would automatically morph into Promise(Of ...)-returning functions (to allow chaining).

I know this is not so easy, but that would be very nice actually.

Oct 1, 2012 at 8:41 PM

Thanks for a great suggestion! As a C# designer, I love the fact that you already consider working without "await" a pain! :-)

We did consider "await" for TypeScript (as you can imagine with Anders and I on the design team) and definitely note your feedback to add it. One thing that concerns us is that there is no good corresponding JavaScript idiom to compile to, so the resulting JavaScript would not be as beautiful and straightforward as what we generate for modules and classes. In fact if you look at the IL we generate for await in C# and VB, it is something no one would want to write on their own!

Arguably the job of a language is to write the ugly stuff for you. So far however we've avoided generating ugly stuff with TypeScript, and the approachability of the generated JavaScript is really valuable, e.g. for in-browser debugging.

A difficult trade-off! We are really looking forward to hearing folk's thoughts on "await".

Oct 1, 2012 at 8:53 PM

It has certainly become a pain since the WinRT framework require one call over two to be asynchronous ;-) Before, it was a similar pain, but occured so much less often we didn't notice.

On the JS side, I think premises introduced by the WinJS framework are nice and to the job properly. Adding the "rest function" as a last callback of a function is also needed to support the "old" Asynchronous paradigm.

It's clear that you'll probably not be able to support on the same level as on .NET (where try/catch can trap exceptions nested from async calls) using those simple tricks, but it's not as if we used try{} blocks a lot in JS (I don't say it's good, it's just how code is usually written).

Oct 1, 2012 at 9:24 PM
Edited Oct 1, 2012 at 9:26 PM

I absolutely think that you guys should add "async/await" support to the language. JavaScript, being primarily a client-side language, is a language where asynchronous requests (or AJAX requests that should be asynchronous) happen all the time, far more often than in server-side C#. Writing complicated asynchronous code by hand in JavaScript can quickly turn into a nightmare of callback pyramids and continuations that is hard to reason about and even harder to maintain.

I think TameJS (link: http://tamejs.org/), and thus Iced CoffeeScript (link: http://maxtaco.github.com/coffee-script/ ) both do a great job of introducing a clean, easier to understand "await" syntax into JavaScript. It is true that it can complicate debugging, but Tame/ICS deal with this by keeping their own "fake" callstack that is passed around to the continuation functions. I think the benefits of easier to write, easier to understand, and thus easier to maintain code far outweigh the disadvantage of having some ugly compiler-generated code.

Right now, the sad truth is that many JavaScript developers simply avoid writing asynchronous code because they find it too hard to reason about. They instead make synchronous AJAX requests, which in a web browser is a really bad idea. An otherwise great library that I use which commits this sin is the very popular SPServices (link: http://spservices.codeplex.com/). Microsoft's could do a great service to the web by making asynchronous code more accessible via a TypeScript "async/await".

Oct 1, 2012 at 9:46 PM

Another thing to consider is that the ES6 generators proposal could be used in conjunction with promises to give an experience close to await. See http://taskjs.org as an example of this.

Oct 1, 2012 at 10:12 PM

I truly believe that adding an await feature would be a massive selling point to the language.  Callback hell can happen very quickly and having an await feature would make the code a LOT cleaner.  Also, source maps will go a long way toward hiding the complexity of the generated code.

Oct 2, 2012 at 1:48 AM

Here was an interesting approach by a library called "synchronize.js" I ran across few days back. http://alexeypetrushin.github.com/synchronize/docs/index.html

The beautify of it is that it does not require any transcompliations of the source code and works in plain javascript without any language modifications. It does require that libraries follow nodejs standards of passing errors as first parameter of the callback.

var sync = require('synchronize');
sync(fs, 'readFile');

sync.fiber(function(){
  try {
    var data = fs.readFile('invalid', 'utf8')
  } catch (err) {
    console.log(err)
  }

});

Oct 2, 2012 at 2:56 PM
Edited Oct 2, 2012 at 2:57 PM

Mads, I'd suggest your team stop focusing on preserving clean JavaScript idioms, and instead focus on powerful TypeScript debugging capabilities within Visual Studio.

As a CoffeeScript user, I know from experience that the desire to remain "just javascript" hampers innovation. And while it's nice to say, "Hey, the compiled JS code will look kinda-sorta like your TypeScript!", the reality is that debugging compiled JS in browser is a painful experience, even in languages which try to preserve JS idioms. 

What we really need is to be able to debug in our source language -- something we've been doing in the Java and .NET world for decades. Debugging generated JavaScript should be as rare an event as debugging compiled assembler.

Instead of focusing on generating clean JS, focus on powerful debugging tools for TS. Debugging TS in Visual Studio. That's what we need. Not only does this give us a much more powerful, productive way to debug our code, but it also frees up the TS team to add powerful language features like await, LINQ, generics, etc.

Oct 2, 2012 at 3:43 PM

+1 for adding await support as syntactic sugar around promises.

+1 for be able to debug TS source files directly. @judahgabriel is right, having to set breakpoints in the generated javascript is like having to debug binary code (ok, not quite, but it's analogous).

+1 for adding LINQ-style queries and richer collection support.

 

Oct 2, 2012 at 4:44 PM
Edited Oct 2, 2012 at 4:45 PM
billyzkid wrote:

+1 for adding LINQ-style queries and richer collection support.

 

LINQ does not actually require language-level support (despite what the acronym stands for). http://linqjs.codeplex.com/

Oct 2, 2012 at 5:23 PM
Edited Oct 2, 2012 at 5:24 PM

Yes, language integration isn't required for list comprehensions and queries, but language support for list comprehensions is a very nice-to-have. LINQ = language-integrated query, after all.

And it's not just C# folks. Python and CoffeeScript also have language level support for list comprehensions, granting much developer happiness. It'd be very welcomed -- and familiar -- to the folks using TypeScript.

Oct 2, 2012 at 5:46 PM

If TypeScript is ever going to add syntactic sugar of LINQ expressions, I think it should do it in a way that looks like JS, not C#. For example:

let query =
   for element of array
   if element > 0
   let square = element * element
   yield square - element;

I think that what could make TypeScript successful where CoffeeScript and Script# remained (relatively) fewly used is that it feels like JavaScript but still brings a sufficient amount of new features that *EVERY DEVELOPER* do love and that will most probably land in plain JS someday. TypeScript isn't made to make C#-ers feel home in JS, but for JS devs to feel home in Visual Studio. This is a whole different story.

What makes TypeScript different is his ability to "forward polyfill" JavaScript, not his ability to be another language. We already have "other languages" that compile to JS, Script# included.

Oct 2, 2012 at 6:10 PM

Agreed, TypeScript should implement query expressions in a JavaScript idiomatic way, rather than a C#, LINQ-like way. 

Oct 3, 2012 at 1:58 AM

Please don't give he clean emitted javascript too easily for the sake of adding more powerful language features.

I really like that TypeScript seems to be compiling to commonly used patterns in JavaScript that I can drop down to and understand.

I think clean JavaScript output should remain as one of the design goals.

Maybe some helper libraries to hide the nastiness in a single included js file could help add more powerful features, but keep the code gen clean.

Oct 3, 2012 at 2:09 PM
Edited Oct 3, 2012 at 2:11 PM

Async/await would be loved, indeed.

Oct 3, 2012 at 2:52 PM
billyzkid wrote:

+1 for adding await support as syntactic sugar around promises.

+1 for be able to debug TS source files directly. @judahgabriel is right, having to set breakpoints in the generated javascript is like having to debug binary code (ok, not quite, but it's analogous).

+1 for adding LINQ-style queries and richer collection support.

 

billyzkid summed it up.

Three great ideas, +1 for each

Oct 17, 2012 at 9:53 AM

As a JS dev i dont think the await keyword is a good idea. Thats a thing you have to handle by yourself and if you can't just compile C# do JS. Lets keep TypeScript as close to JS as possible, adding only the most important missing part which are optional types.

Oct 17, 2012 at 2:28 PM

Interesting. There really seems to be 2 camps of TS users here: those who say TS should be "JavaScript + types", and those who say TS should care about powerful language features more than JS compatibility.

As a CoffeeScript user, I find the JS compatibility to be stifling. So, I'm leaning towards the 2nd camp: give me powerful language features over JS compat.

Oct 17, 2012 at 8:55 PM
Edited Oct 17, 2012 at 8:58 PM

FWIW, I have an experimental support of typescript in streamline.js.This may be a stopgap solution until MS comes up with a solution (if they do).

Oct 17, 2012 at 9:51 PM
judahgabriel wrote:

Interesting. There really seems to be 2 camps of TS users here: those who say TS should be "JavaScript + types", and those who say TS should care about powerful language features more than JS compatibility.

As a CoffeeScript user, I find the JS compatibility to be stifling. So, I'm leaning towards the 2nd camp: give me powerful language features over JS compat.

People just need to get over the "keep it close to JavaScript" mentality.  It's a fact that JS is the assembly language of the web.  We have a whole array of languages that already compile to JS including crazy things like emscripten.  We need the browser vendors to fully embrace source maps and make them work even better than they already do.  Source maps are basically pdb files for the browser platform.  Source maps give us developers choice.  And I for one, am not a fan of having only a single language choice to write web applications in.  Anyone who says that we don't need anything other than JS is basically saying that we should write everything in assembly and that we don't need technology to advance.

Oct 17, 2012 at 11:28 PM

The real problem here is the evolution of JavaScript.  I think it's a good goal and principle that regular JavaScript is also valid TypeScript.  If TypeScript adds too many constructs then there is a risk that the paths of the two languages will diverge - and it will be impossible to maintain base level language parity.

That said, back to the original point of the post, the value of an 'await' keyword that could leverage a duck-typed IPromise interface (or even a callback parameter pattern) would be incredibly useful. 

Oct 17, 2012 at 11:57 PM
Edited Oct 18, 2012 at 12:01 AM

So this is certainly no replacement for language based 'await' support but I thought I'd offer up a bit of TypeScript code I wrote that provides a strongly typed alternative to traditional promises.

Promises are currently the defacto standard for async programming in JavaScript and when compared with the traditional callback approach to async programing there's no doubt they're superior.  What I don't like about promises though is:

  1. error handling is optional.  Since the done & fail callbacks are seperate nothing forces you to actually implement error handling.
  2. if you do implement error handling you never know what you're going to get as there's no forced consistancy around how errors are returned.
  3. when it comes to TypeScript its cumbersome at best to strongly type the return value of a promise.

With the Result pattern below I set out to adress the above while maintaining compatability with the existig promise model of async programming. 

The code below starts by defining standard IPromise & IDeferred interfaces that will duck type to both jQuery and WinJS concepts of a promise.  Then I define a new class called a Result that implements a simplified IResult interface.  This IResult interface can be easily strongly typed through interface inheritance and I provide a few typings for the built in data types.  Following that is a usage example which I'll break down after the code jump:

// Standard Promise & Deferred interfaces
interface IPromise {
	done(onDone: () => void): IPromise;
	then(onDone: () => void, onFail: () => void): IPromise;
}

interface IDeferred extends IPromise {
    reject(...args: any[]): void;
    rejectWith(context, args?: any[]): void;

    resolve(...args: any[]): void;
    resolveWith(context, args?: any[]): void;
}


// Result class for simplyfied async communication (with added Promise support)
class Result implements IResult {
    // Private member vars
    private val = null;
    private handlers: { (result: IResult): void; }[] = [];
    private err: Error = null;
    private resolved = false;

    // Public methods

    public value(val?: any): any {
        if (!this.resolved) {
            this.val = val;
            this.resolve();
        } else if (this.err != null) {
            throw this.err;
        }
        return this.val;
    }

    public wait(onDone: (result: IResult) => void): IResult {
        if (this.resolved) {
            onDone(this);
        } else {
            this.handlers.push(onDone);
        }
        return this;
    }

    public error(err?: Error): Error {
        if (!this.resolved) {
            this.err = err;
            this.resolve();
        }
        return this.err;
    }

    // Private methods
    private resolve() {
        this.resolved = true;
        for (var i = 0; i < this.handlers.length; i++) {
            try {
                this.handlers[i](this);
            } catch (e) {
            }
        }
    }

    // Static methods
    static error(err?: Error): IResult {
        var result = new Result();
        result.error(err || new Error());
        return result;
    }

    static value(val?: any): IResult {
        var result = new Result();
        result.value(val);
        return result;
    }

    static wait(promise: IPromise, onDone: (result: IResult) => void, errorMsg?: string): IResult {
        return wrap(promise, errorMsg).wait(onDone);
    }

    static wrap(promise: IPromise, errorMsg?:string): IResult {
        var result = new Result();
        promise.then(function () {
            // Signal success
            var val = arguments.length > 0 ? (arguments.length == 1 ? arguments[0] : arguments) : null;
            result.val(val);
        }, function () {
            var msg = errorMsg ? errorMsg : (arguments.length > 0 ? arguments[0] : '');
            switch(typeof msg) {
                case 'error':
                    result.error(<any>msg);
                    break;
                case 'string':
                    result.error(new Error(<any>msg));
                    break;
                default:
                    result.error(new Error());
                    break;
            }
        });
        return result;
    }
}

interface IResult {
    wait(onDone: (result: IResult) => void ): IResult;
    value(val?: any): any;
    error(err?: Error): Error;
}

interface IBoolResult extends IResult {
    wait(onDone: (result: IBoolResult) => void ): IBoolResult;
    value(val?: bool): bool;
}

interface IDateResult extends IResult {
    wait(onDone: (result: IDateResult) => void ): IDateResult;
    value(val?: Date): Date;
}

interface IFunctionResult extends IResult {
    wait(onDone: (result: IFunctionResult) => void ): IFunctionResult;
    value(val?: (...args: any[]) => any): (...args: any[]) => any;
}

interface INumberResult extends IResult {
    wait(onDone: (result: INumberResult) => void ): INumberResult;
    value(val?: number): number;
}

interface IStringResult extends IResult {
    wait(onDone: (result: IStringResult) => void ): IStringResult;
    value(val?: string): string;
}

interface IVoidResult extends IResult {
    wait(onDone: (result: IVoidResult) => void ): IVoidResult;
    value(): void;
}


// Usage example

function getDelayedValue(error: bool): IStringResult {
	var result: IStringResult = new Result();
	setTimeout(function () {
		if (error) {
			result.error(new Error('something went wrong'));
		} else {
			result.value('hello world');
		}
	}, 100);
	return result;
}

for (var i = 0; i < 2; i++) {
	getDelayedValue(i > 0).wait(function (result) {
		try {
			var message = result.value();
			alert(message);
		} catch (e) {
			alert(e.message);
		}
	});
}

So the easiest way to understand how this works is to look at the example usage above.  A Result is really designed to model the 80% case of invoking a method and asynchronously waiting on a result.   Lets first look at how this works from the callees perspective.

We have a function called getDelayedValue() which is strongly typed to return an IStringResult. Basically this function is asynchronosly going to return a string to the caller.  Within the function we create a new Result object (same way you'd create a new Deferred in jQuery) and strongly type it to be an instance of IStringResult.  We then do our async thing and return the resultant value to the caller using the strongly typed result.value() call.  If an error occurs we can pass that to the caller as a new Error instance via a call to result.error().  That's it for the callee side.

On the caller side we invoke getDelayedValue() and what we get back is an IStringResult that we can call the now strongly typed wait() method on.  The callback for wait() always takes a single argument which is a stringly typed Result object.  To get the returned value you simply say "var x = result.value();" but you'll want to do that within a try { } catch() { } because an exception will be raised if an error occured.

What's nice about this pattern is that there's only one thing you can do with a result, which is call wait(), and that call takes a single parameter callback that can be easily type checked by the compiler.  You're then forced to handle errors which I feel is a weakness of promises.  There's then a standardized format for reporting errors so you can more easily create a common UI for displaying errors (If you're not familiar with the Error class this is how built in exceptions get reported.)  And with the above code I've built in support for wrapping a traditional Promise so interoperating with existing libraries is straight forward.

As a side note... I could have broken IResult into seperate caller & callee pieces which would resulted in the caller only seeing a wait() method returned from the callee but that would mean having to derive from two different interfaces when you want to stringly type things which i felt was cumbersome.  So the above code is what I consider the good enough implementation until support for generics comes along... 

Oct 19, 2012 at 5:50 PM

Now that we know you guys are supporting source maps with TypeScript, I see zero reason not to do this feature. The benefits are huge, and the cost is very low with proper browser support of source maps (which is only getting better and better in Chrome/FireFox). 

Oct 24, 2012 at 3:24 AM
Edited Oct 24, 2012 at 3:25 AM

I am awaiting the new operator. :P But seriously, I'd love to have await in TypeScript. And I recall you mentioning that there is no idiom for which the await operator would compile to, meaning that the underlying code would be messy, or ugly - but really, who cares? Javascript, in my opinion is already a pretty ugly-looking language to begin with.

Oct 24, 2012 at 10:38 AM

For now you could use the Async.js library which provides a number of control flow functions like series, parallel, waterfall and more.

Oct 24, 2012 at 11:11 AM

Generators are the way to go (ES6 proposal).

Oct 24, 2012 at 2:20 PM

There's no need to speculate, if you want async/await/yield – just go implement it. The source code is in the open. 

Oct 24, 2012 at 2:21 PM
Edited Oct 24, 2012 at 2:22 PM

duplicate

Oct 24, 2012 at 2:21 PM
Edited Oct 24, 2012 at 2:22 PM

duplicate 

Nov 27, 2012 at 11:54 PM

+1 ES6 generators

The big 3 (IE, Chrome, & Firefox) have made significant progress towards implementing the same standard.  With out getting on a tangent about the pros & cons of standars and inovation... We should continue to give them a browsers the chance to proceed down the standards path.  The goal shouldn't be to diminish javascript as the assembler of the web while focusing on making an all powerful higher level language. Can't we use the typescripts & IcedCoffees of the web as stop gaps until  we get a universally better web via much improved javascript?

@ickman Great Code - I'm guessing in a pre ES6 implementation, any typescript implementation would use a similar model underneath the syntactical sugar.  Similar to LINQ syntax using System.Enumerable and IQueryable under the covers of from/select/where etc...

Dec 15, 2012 at 11:33 PM
Edited Dec 15, 2012 at 11:38 PM

Async code is readily handled by external libraries; I use jQuery and ickman has given a TypeScript implementation above. The model for TypeScript appears to be Turbo Pascal and we managed to build some pretty decent application back then. I would vote to keep TypeScript to the essentials: modules and classes make large javascript applications manageable, variable typing and compile time error detection are a huge time saver. Anything else should be hived off into the equivalent of a run-time library. TypeScript is a community project, anyone want to make a start on TSlib?

Dec 16, 2012 at 3:31 PM
stanthomas wrote:

Async code is readily handled by external libraries; I use jQuery and ickman has given a TypeScript implementation above. The model for TypeScript appears to be Turbo Pascal and we managed to build some pretty decent application back then. I would vote to keep TypeScript to the essentials: modules and classes make large javascript applications manageable, variable typing and compile time error detection are a huge time saver. Anything else should be hived off into the equivalent of a run-time library. TypeScript is a community project, anyone want to make a start on TSlib?

Have you ever used async/await in C# or await in TameJS/IcedCoffeeScript? My guess from your post would be not. async/await are not for replacing Promise-based libraries, they are for complementing them.

With async/await, you can write code essentially as if it were synchronous code. It is impossible for any library to accomplish the same, no matter how good. You inevitably end up transforming the structure and flow control of your code to match the asynchronous behavior requirements, which in turn means even the slightest change in the way you want to structure asynchronous calls means large transformations to your code base. It also is harder to follow the logic of code written in this way.

I myself use JQuery's Deferred object extensively. It is definitely far better than writing my own library or my own primitive code to handle asynchrony, but it is no where near as elegant as it would be with language-level support for async/await. A great example of this in C# would be the TPL (task-parallel library) from .NET 4.0. It could do asynchrony (Tasks are Promise-like objects very similar to JQuery's Deferred), but it became much easier to use and therefore much more useful once async/await were introduced with C# 5/.NET 4.5.

Dec 16, 2012 at 8:13 PM

Just noticed someone created a pull request for TypeScript to support ES6 generators (and some other ES6 goodies).

Right now the generated JS code would only run on Firefox as that is the only platform supporting generators far as I know. But at least it opens up the door to create an await like library in TypeScript and see how it works out.

// Peter

Dec 17, 2012 at 8:25 PM
MgSam wrote:
Have you ever used async/await in C# or await in TameJS/IcedCoffeeScript? My guess from your post would be not. async/await are not for replacing Promise-based libraries, they are for complementing them.

You guess correctly. I'm a C++ guy (and Pascal / C in the dark mists of time before that) but this forum isn't the place for my views on C#.

My view remains that there is a readily available library-based approach to this problem and TypeScript's simple elegance should not be complicated by throwing the kitchen sink at it. I don't have a problem with async code that looks like async code.

Jan 10 at 12:31 AM
Plus 1 on await keyword. I did not think I would have needed in c# either, but I love it now.
Thanks.
Jan 13 at 8:18 PM
Edited Jan 13 at 8:25 PM
I am also strongly in the camp of people who no longer care (much) about the ugliness of the javascript output as long as there is support for source maps. It really doesn't matter much anymore for most development. I wouldn't say you should go completely crazy with the output, but I think converting async/await into a function using promises is straightforward enough to pass under the cost/benefit threshold with room to spare.

I would recommend that you support the Promise/A specification (compatible with the Angular and Q implementations), or perhaps optionally (as in a compiler flag) a different specification if needed for WinJS/JQuery promises (sorry, not as familiar with these myself). Note that a single application might have to support two or more conventions, but in that case I would say either pick one and have us write our own adapters, or else have some additional syntax to specify the convention when "awaiting" an operation or defining an async function.

Promise chains in the output would not be too difficult to read relative to the original async/await code. They both have generally the same "shape", with the javascript version just being slightly more verbose. To me, this is on the same level of transformation as, say, converting an ES6 class to a constructor function, or converting multi-level TypeScript modules to AMD modules.

One limitation might be that we wouldn't be able to support code that requires the compiler to create a new promise. I can't think of a good example where this would be needed, however.

That being said, here is a simplified example of what async/await in TypeScript might look like, and what I would expect the output might be when using angular promises (in this case the generator doesn't need to produce a new promise):
        async getDataAsync(): ng.IPromise<Item[]> {
            var response = await this.$http.get("/api/data");
            return _.map(_response.data, function (item: { firstName: string; lastName: string }): Item {
                return new Item(item.firstName, item.lastName);
            });
        }
And here would be the generated output. Not too bad for a simple example, though some name munging might be required:
            MyDataService.prototype.getData = function () {
                var response = this.$http.get("/api/data");
                return response.then(function (_response) {
                    return _.map(_response.data, function (item) {
                        return new Item(item.firstName, item.lastName);
                    });
                });
            };
Here, TypeScript only needs to assume that the expression to the right of await conforms to the Promises/A specification in order to produce the right transformation. It could be any implementation that conforms to this interface. In this case, we're using Angular's promise implementation.

Here is an example showing two awaits, showing the need for some analysis on closure values to determine what to output:

Example 1: Callback for second await is not registered until the first await resolves successfully
        async getDataAsync(): ng.IPromise<{ data: Item[]; foo any; status: number }> {
            var response = await this.$http.get("/api/data");
            var data = _.map(response.data, function (item: { firstName: string; lastName: string }): Item {
                return new Item(item.firstName, item.lastName);
            });
            var fooResponse = await this.$http.get("/api/foo");
            return {
                data: data,
                foo: fooResponse.data,
                status: response.status 
            };
        }

// expected output:
            MyDataService.prototype.getData = function () {
                var response = this.$http.get("/api/data");
                return response.then(function (_response) {
                    var data = _.map(_response.data, function (item) {
                        return new Item(item.firstName, item.lastName);
                    });
                    return this.$http.get("/api/foo").then(function (_fooResponse) {
                        return {
                            foo: _fooResponse.data,
                            data: data,
                            status: _response.status
                        };
                    });
                });
            };
Example 2: callbacks for both awaits can be registered immediately
        async getDataAsync(): ng.IPromise<{ data: Item[]; foo: any }> {
            var response = await this.$http.get("/api/data");
            var data = _.map(response.data, function (item: { firstName: string; lastName: string }): Item {
                return new Item(item.firstName, item.lastName);
            });
            var fooResponse = await this.$http.get("/api/foo");
            // we don't anything from response above, just the return value of the previous promise
            return {
                foo: fooResponse.data,
                data: data
            };
        }

// expected output:
            MyDataService.prototype.getData = function () {
                var response = this.$http.get("/api/data");
                return response.then(function (_response) {
                    var data = _.map(_response.data, function (item) {
                        return new Item(item.firstName, item.lastName);
                    });
                    return data;
                }).then(function (data) {
                    return this.$http.get("/api/foo").then(function (_fooResponse) {
                        // note how we have to wait to register this callback so we can close over data above
                        return {
                            foo: _fooResponse.data,
                            data: data
                        };
                    });
                });
            };
Another topic is try/catch/finally. This is supported by by the conventions and interface of the Promises/A spec. The transformation would in most cases be straightforward. Here's a simple example:
        async processData(): ng.IPromise<any> {
            this.loading = true;
            var item: Item;
            try {
                item = await this.getData();
                this.$log.info("Success! here's a firstName: " + item.firstName);
            } catch (error: any) {
                this.$log.error("Oops! Logged an error: " + error.toString());
                throw error;
            } finally {
                this.loading = false;
            }
        }
And here is the expected output, more or less:
            MyDataService.prototype.processData = function () {
                var _this = this;
                var response = this.getDataImpl();
                this.loading = true;
                var ret = response.then(function (item) {
                    _this.$log.info("Success! here's a firstName: " + item.firstName);
                }, function (error) {
                    _this.$log.error("Oops! Logged an error: " + error.toString());
                    throw error;
                }).finally(function () {
                    _this.loading = false;
                });
                return ret;
            };
So, obviously more complicated examples will have more complicated transformations, but what I've tried to demonstrate is that in most cases, the transformation from async/await to Promises is pretty straightforward and the output is still relatively readable and has the same basic structure of the original.
Jan 14 at 8:02 AM
Note that this piece:
                }).finally(function () {
                    _this.loading = false;
                });
should be:
                }).then(function () {
                    _this.loading = false;
                });
As this function will be called regardless of the promise status (resolved/rejected).

You suggestion of using Promises has the advantage of automatically working with all promises implementations as long as we use 'then' method (promises return 'thenable' objects http://promises-aplus.github.io/promises-spec/ ).

I think a bigger problem would be rewriting loop constructs:
var results = [], result: any;
while(condition()) {
  result = await fun();
  results.push(result);
}
return results;
Of course this can be done as demonstrated by C#'s yields but I wonder if it will ever be implemented by TypeScript team as ES6 generators (that are already available in Firefox and Chrome behind a flag) solve exactly the same issue. See: http://taskjs.org/

Not that I wouldn't like this feature to be implemented - having await and being able to target older browsers would be really nice!
Jan 14 at 2:26 PM
Edited Jan 14 at 2:34 PM
I believe finally is the more correct choice. Here, the promise returned by finally doesn't modify the return value of the target promise. Also, finally can indeed be called regardless of the promise status - resolved/rejected. Here is what finally might look like if all you had is 'then', assuming that 'then' can be called multiple times to register multiple callbacks in the promise implementation:
var getTransformedValuePromise = function() {
  // normal operation
  var transformValue = function(value) { return value + 1; }
  var ret = getPromise().then(transformValue);

  // simulating a finally
  var finallyCallback = function() { return doCleanup(); }
  ret.then(finallyCallback, finallyCallback);

  // the returned promise resolves to the return value of transformValue, not finallyCallback
  return ret;
};
Good point about await within logical structures. I would be ok with a "version 1" that didn't include support for await within a loop/conditional/etc.... However, if implemented, there would need to be an ES5 fallback implementation for some years yet. Compiling await to yield+promises (or ES5 fallback) would, however, be much less similar to the original code than my examples above. This wouldn't matter to me personally - I don't really mind having some complicated transformations happening behind the scenes when it's useful and predictable, as it is in this case.
Jan 18 at 8:06 PM
Edited Feb 7 at 8:16 PM
I found an article describing how to connect promises and generators for await/async-like workflow:

http://www.html5rocks.com/en/tutorials/es6/promises/

Chapter: "Bonus round: Promises and Generators"
Jul 8 at 12:12 AM
Edited Jul 8 at 12:14 AM
FremyCompany wrote:
If TypeScript is ever going to add syntactic sugar of LINQ expressions, I think it should do it in a way that looks like JS, not C#.
.
.
Making LINQ syntax collection-focused in C# was a huge mistake. The collection-oriented syntax makes it really awkward to leverage for other monads.
Please don't repeat this mistake in TypeScript and make it look like what it really is - monadic comprehension.

For example:
var query = do {
   x <- array
   when( x > 0 )
   y <- anotherArray
   z <- getThirdArray( x, y )
   var w = someFunc( z + x )
   w + x + z
};
(yes, I do love me some Haskell, but I'm open to other syntactic alternatives, as long as they are generic like that)

Bonus - generic monadic syntax works just as well for async computations:
var resultingPromise = do {
  tpl <- loadTemplate( "http://some.site.com/whatever.template.html" )
  when( tpl != null )
  rendered <- renderAsynchronously( tpl, someContext )
  var element = document.createElement("div")
  element.innerHTML = renreded
  element
};