General Interface is an open source project hosted by the Dojo Foundation

Designing Asynchronous Functions

The function passed to $Y (the wrapped function) must take exactly one parameter, cb, which is an instance of jsx3.$AsyncCB. The function must synchronously or asynchronously call the done() method once on cb. The parameter sent to cb.done() is the asynchronous return value.

In most cases, the synchronous return value (the argument of the return statement) of the function is ignored.

Declare a method to be asynchronous with $Y when it performs an asynchronous operation and needs to communicate its completion to client code. Keep in mind that there are only a few types of asynchronous operations in JavaScript:

  • Loading a JavaScript file or using XMLHttpRequest (jsx3.net.Request)
  • Waiting for user input
  • window.setTimeout/jsx3.sleep
  • Other Y functions

Method Parameters

You can call the wrapping function with any parameters.

Because the wrapped function takes exactly one parameter, cb, the parameters passed to the wrapping function are accessible via cb.args(). For example:

var asyncFct = jsx3.$Y(function(cb) {
    jsx3.log("asyncFct called with args " + cb.args());
    cb.done();
});

Return Value

You can define an asynchronous return value by passing it to cb.done().

The return value is passed to any callback registered with when(). It is also retrievable via the rv() method of jsx3.$AsyncRV. For example:

var asyncFct = jsx3.$Y(function(cb) {
    cb.done("Hello World");
});

// Logs "Hello World"
asyncFct().when(function(rv) { jsx3.log(rv); });

Return Value Chaining

An asynchronous function can return a local instance of jsx3.$AsyncRV produced by a call to another asynchronous function. This can eliminate the need for a call to when() and an anonymous function. For example:

var asyncFct = jsx3.$Y(function(cb) {
    return loadXmlAsync(cb.args()[0]);
});

asyncFct("data1.xml").when(function(doc) {
    jsx3.log("Got document " + doc);
});

The previous code is a more concise form of the following:

var asyncFct = jsx3.$Y(function(cb) {
    loadXmlAsync(cb.args()[0]).when(function(doc) {
        cb.done(doc);
    });
});

asyncFct("data1.xml").when(function(doc) {
    jsx3.log("Got document " + doc);
});

Putting It All Together

Parameter resolution and return value chaining allow you to write asynchronous methods that look just like synchronous methods, thereby improving readability and usability.

var mergeTwoURLs = jsx3.$Y(function(cb) {
    var args = cb.args();
    var url1 = args[0], url2 = args[1];
    var doc1 = loadXmlAsync(url1),
        doc2 = loadXmlAsync(url2);
    return merge(doc1, doc2);
});

var merge = jsx3.$Y(...);

In an application in which many business logic functions depend on asynchronous primitives, $Y allows you to make these functions asynchronous without requiring extensive boilerplate code.
 

You cannot use variables of type jsx3.$AsyncRV with control statements, such as if. However, parameter resolution allows you to use parameters with control statements. As a workaround, you can pass such variables to another function.

Contents

Searching General Interface Docs

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.