Skip to content
Switch branches/tags
Go to file

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Build Status Logo


$async is an async/await implementation based on generators for use with angular.


npm install ng-async


As service

import ngAsync from 'ng-async';

angular.module('my-module', [])
	.controller('my-controller', function($async) {
		const init = $async(function*() {
			const { data : users } = yield $http.get('/users');
			$scope.users = users;

To wrap a service/controller

import ngAsync, { $async } from 'ng-async';

angular.module('my-module', [])
	.controller('my-controller', $async(function*($http) {
		const { data : users } = yield $http.get('/users');
		$scope.users = users;

Note: To wrap a service/controller it must be explicitly annotated. The example uses ng-annotate to do it for us.

Note: keep in mind that an $async function returns a promise, not a value. This is especially important with factories, since their return value will be used for injection.


  • ES6 support in either your host environment or your build chain. At minimum your environment should support the following:
    • Generators
    • Modules
    • Lambdas
    • const/let
    • Rest parameters
  • Angular should be available to the module via the module loader with import 'angular'.
  • Angular ^1.3.0


ES7 introduces async functions, which create a way to write asynchronous code with a synchronous syntax. Unfortunately this doesn't work well with Angular: code after a call to await does not run in the digest cycle, and thus it won't update the screen. To illustrate:

	<li ng-repeat="user in users">
	  {{ }}
$scope.users = [];
async function init() {
	const { data : users } = await $http.get('/users');
	//This does not run in a digest cycle
	$scope.users = users;

Since the $scope.users = users; line does not run in a digest cycle, the view isn't updated. To solve this with async functions you need to put $scope.$apply calls after each awaited statement.

$async implements similar functionality with the help of generators in such a way that all code in an $async function does run in the digest cycle.

How should I use it?

Usage of $async is very similar to usage of plain async functions. Instead of creating an async function you should pass a generator function to $async, and where you would use await in an async function you now need to use yield. Additionally you don't need the $scope.$apply calls anymore.

//with async functions
async function foo() {
	$scope.someStuff = await getSomeStuffAsync();
	$scope.someOtherStuff = await getSomeOtherStuffAsync();
	console.log("we're done");

//equivalent with $async, but angular proof:
const foo = $async(function*() {
	$scope.someStuff = yield getSomeStuffAsync();
	$scope.someOtherStuff = yield getSomeOtherStuffAsync();
	console.log("we're done");

How can I pass arguments to an $async function and what happens with this?

Arguments are directly passed to the generator function and the this that is used to call the $async function will also be used for the generator function. Example:

const myObj = {
	bar : $async(function*(a, b) {
		console.log(`a: ${a}`);
		console.log(`b: ${b}`);
		console.log(`this === myObj: ${this === myObj}`);
}, 2);
//a: 1
//b: 2
//this === myObj: true


No description, website, or topics provided.



No packages published