GithubHelp home page GithubHelp logo

promises-titanium's Introduction

Promises Titanium Example Build Status

An example on using promises in a Titanium application.

The master branch uses Alloy. If you want to see examples based on just the API without Alloy check out the non_alloy branch.

Table of Contents generated with DocToc

Getting Started

First make sure you have a working titanium environment. NPM will install titanium as a dependency however, it still needs to install the SDK manually. It is recommended you install titanium globally first.

$ npm install -g titanium
$ titanium sdk install 3.1.3.GA

Once ready run the following in the projects working directory.

$ npm install .
$ npm start             # start server and compile app OR
$ npm run-script debug  # for verbose debug output

This will spawn a small express server for demo uses and then will build the application and spawn it in the iOS simulator.

How promises are used in titanium

Promises offer a convenient way to make syntactical and logical sense of the confusing nature of asynchronous code. If your reading this then you most likely know what the patterns are surrounding callbacks and the difficulties they pose in code readability and consistency.

In this project I outlined three use cases where asynchronous code is used and how promises could be implemented to help.

Timeouts / delays

setTimeout offers a convenient way to delay things. A sample implementation of such a function could look like:

function delayed(ms) {
  var defer = Q.defer();
  setTimeout(defer.resolve, ms);
  return defer.promise;
}

delayed(1000).then(function () {
  console.log("It finished!");
});

// Q does this for you with Q.delay()

A timeout loop is illustrated in app/lib/timeout_promiser.js. This pattern can be useful to break up long running processing into small chunks allowing the current JavaScript context to avoid getting blocked.

Modal windows / controls

Sometimes user interaction is required but your only interested in a one time result. Unlike events which are triggered more than once. Some user interaction is one-off. For example a popup message with choices. Or a modal login screen.

An example of such a component is in app/controllers/modal_popup.js.

HTTP Requests

One of the most common use cases is to handle HTTP request. Several implementation exist which convert to promises. The most basic is illustrated in app/lib/http_client.js which uses the Titamium.Network.HTTPClient module.

For an example on the simplicity of making a promise based getter method that uses Node's HTTP module (this is not Titanium but here for reference and illustration):

http = require('http');
function httpGet(url) {
  var data = "", defer = Q.defer();
  http.get(url, function (res) {
    if (res.statusCode !== 200) {
      defer.reject("Bad HTTP: " + res.statusCode);
      return;
    }
    res.on("error", defer.reject);
    res.on("data", function(chunk) { data += chunk; });
    res.on("end", function() { defer.resolve(data); });
  });
  return defer.promise;
}

// JSON: {"message":"test"}
httpGet("http://example.com/sample.json")
  .then(JSON.parse)
  .get("message")
  .then(console.log, console.log)
  .done();

Tests

This project uses jasmine-node to run tests on the application. It is Node based and therefore uses a mocked out version of the Titanium API. Keeping this in mind that tests only test the behaviour of the code written in this application and not the Titanium API. Which means testing that views render correctly is out of scope with this setup.

You run the tests with:

$ npm test

The examples used illustrate how to properly handle the asynchronous nature of promises. Synchronous assumptions in the usual tests will fail or offer inconsistent results when promises are used and require the tests to be written asynchronously.

Example specs in Jasmine

When testing promise code in Jasmine you have to remember that despite using any mock timer all methods in the Q library implementation are asynchronous.

The following example WILL HAVE PROMBLEMS:

describe "A broken test for promises", ->
  it "should call the callback but will fail instead", ->
    callback = createSpy "callback"
    promise = functionReturnsAResolvedPromise()
    promise.then(callback)
    expect( callback ).toHaveBeenCalled()

The reason is that the then method will return immediately but not run the callback to next tick. So when we attempt to see if the spy was called it hasn't yet.

To fix this use an asynchronous test pattern:

describe "A working test for promises", ->
  beforeEach ->
    @promise = functionReturnsAResolvedPromise()

  it "should call the callback", ->
    ready = false # a flag to poll for when the test can continue
    callback = createSpy "callback"
    runs ->
      # force the flag to finish execution regardles of state of promise.
      @promise.fin -> ready = true # turn the flag to true
      @promise.then(callback)
    waitsFor (-> ready), "promise to be resolved", 10
    runs ->
      expect( callback ).toHaveBeenCalled()
      # Always offer a way for unhandle exceptions to get re-thrown
      @promise.done()

A little but more code but now we can guarantee that when we expect the callback to have been called the then method will have had a chance to finish.

License

Promises Titanium Example by Devin Weaver is dual licensed under a Creative Commons Attribution 3.0 Unported License and a Do What You Want To 3.0 Public License.

Creative Commons License

promises-titanium's People

Contributors

sukima avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.