DoneJS StealJS jQuery++ FuncUnit DocumentJS
6.6.1
5.33.3 4.3.0 3.14.1 2.3.35
  • About
  • Guides
  • API Docs
  • Community
  • Contributing
  • Bitovi
    • Bitovi.com
    • Blog
    • Design
    • Development
    • Training
    • Open Source
    • About
    • Contact Us
  • About
  • Guides
  • API Docs
    • Observables
      • can-bind
      • can-compute
      • can-debug
      • can-deep-observable
      • can-define
      • can-define/list/list
      • can-define/map/map
      • can-define-backup
      • can-define-stream
      • can-define-stream-kefir
      • can-event-queue
      • can-kefir
      • can-list
      • can-map
      • can-map-compat
      • can-map-define
      • can-observable-array
      • can-observable-object
        • behaviors
          • async
          • default
          • enumerable
          • get
          • get default()
          • identity
          • required
          • serialize
          • set
          • type
          • value
        • static
          • propertyDefaults
          • props
          • seal
        • prototype
          • get property()
          • set property()
        • types
          • DefinitionObject
          • Property
      • can-observation
      • can-observation-recorder
      • can-observe
      • can-simple-map
      • can-simple-observable
      • can-stream
      • can-stream-kefir
      • can-value
    • Views
      • can-attribute-observable
      • can-component
      • can-observable-bindings
      • can-stache
      • can-stache-bindings
      • can-stache-converters
      • can-stache-element
      • can-stache-route-helpers
      • can-view-autorender
      • can-view-callbacks
      • can-view-import
      • can-view-live
      • can-view-model
      • can-view-parser
      • can-view-scope
      • can-view-target
      • steal-stache
    • Data Modeling
      • can-connect
      • can-connect-ndjson
      • can-connect-tag
      • can-define-realtime-rest-model
      • can-define-rest-model
      • can-fixture
      • can-fixture-socket
      • can-local-store
      • can-memory-store
      • can-ndjson-stream
      • can-query-logic
      • can-realtime-rest-model
      • can-rest-model
      • can-set-legacy
      • can-super-model
    • Routing
      • can-deparam
      • can-param
      • can-route
      • can-route-hash
      • can-route-mock
      • can-route-pushstate
    • JS Utilities
      • can-assign
      • can-define-lazy-value
      • can-diff
      • can-globals
      • can-join-uris
      • can-key
      • can-key-tree
      • can-make-map
      • can-parse-uri
      • can-queues
      • can-string
      • can-string-to-any
    • DOM Utilities
      • can-ajax
      • can-attribute-encoder
      • can-child-nodes
      • can-control
      • can-dom-data
      • can-dom-events
      • can-dom-mutate
      • can-event-dom-enter
      • can-event-dom-radiochange
      • can-fragment
    • Data Validation
      • can-type
      • can-validate
      • can-validate-interface
      • can-validate-legacy
      • can-validate-validatejs
    • Typed Data
      • can-cid
      • can-construct
      • can-construct-super
      • can-data-types
      • can-namespace
      • can-reflect
      • can-reflect-dependencies
      • can-reflect-promise
      • can-types
    • Polyfills
      • can-symbol
      • can-vdom
    • Core
    • Infrastructure
      • can-global
      • can-test-helpers
    • Ecosystem
    • Legacy
  • Community
  • Contributing
  • GitHub
  • Twitter
  • Chat
  • Forum
  • News
Bitovi

async

  • Edit on GitHub

async Specify an asynchronous property whose value will be resolved later. async properties are computed and automatically update themselves when a dependent observable value is changed.

async( resolve(value), [ lastSetValue ] )

Asynchronously defines the behavior when a value is read on an instance.

Only observed properties (via on, addEventListener, etc) will be passed the resolve function. It will be undefined if the value is not observed. This is for memory safety.

Specify async like:

import { ObservableObject } from "can/everything";

class AppViewModel extends ObservableObject {
  static props = {
    customerId: Number,
    customer: {
      async(resolve) {
        Customer.get({ id: this.customerId })
          .then(customer => {
            resolve(customer);
          });
      }
    }
  };
}

You can also return a Promise rather than calling resolve.

import { ObservableObject } from "can/everything";

class AppViewModel extends ObservableObject {
  static props = {
    customerId: Number,
    customer: {
      async(resolve) {
        return Customer.get({ id: this.customerId });
      }
    }
  };
}

Parameters

  1. resolve {function(value)|undefined}:

    Updates the value of the property. This can be called multiple times if needed. Will be undefined if the value is not observed.

  2. lastSetValue {*}:

    The value last set by instance.propertyName = value.

Returns

{*|Promise}:

The value of the property before resolve is called, or a Promise that will resolve with the value.

Use

Async methods are useful for:

  • Virtual properties that derive their value from an asynchronous action.
  • Defining properties that store a value from another property that is a Promise.

Asynchronous virtual properties

Often, a virtual property's value only becomes available after some period of time. For example, given a personId, one might want to retrieve a related person:

import { ObservableObject } from "can/everything";

class AppState extends ObservableObject {
  static props = {
    personId: Number,
    person: {
      async( resolve, lastSetValue ) {
        Person.get( { id: this.personId } )
          .then( function( person ) {
            resolve( person );
          } );
      }
    }
  };
}

Asynchronous properties should be bound to before reading their value. If they are not bound to, the async function will be called each time.

The following example will make multiple Person.get requests:

const state = new AppState( { personId: 5 } );
state.person; //-> undefined

// called sometime later /* ... */
state.person; //-> undefined

However, by binding, the compute only reruns the async function once personId changes:

const state = new AppState( { personId: 5 } );

state.on( "person", function() {} );

state.person; //-> undefined

// called sometime later
state.person; //-> Person<{id: 5}>

A template like can-stache will automatically bind for you, so you can pass state to the template like the following without binding:

const template = stache( "<span>{{person.fullName}}</span>" );
const state = new AppState( {} );
const frag = template( state );

state.personId = 5;
frag.childNodes[ 0 ].innerHTML; //=> ""

// sometime later
frag.childNodes[ 0 ].innerHTML; //=> "Lincoln Meyer"

The magic tags are updated as personId, person, and fullName change.

CanJS is part of DoneJS. Created and maintained by the core DoneJS team and Bitovi. Currently 6.6.1.

On this page

Get help

  • Chat with us
  • File an issue
  • Ask questions
  • Read latest news