5.14.2

Async Tasks and Promises

In some cases, Fine Uploader uses "promises", both internally and via the API. Promises are a design pattern taken from the functional programming style and are extremely helpful when dealing with asynchronous operations.

Fine Uploader's support for promises is encapsulated in the qq.Promise module. Starting with version 5.0, you can use any A+ certified promise implementation to communicate with Fine Uploader as well. That is, you are no longer bound to qq.Promise. Instead, you can use Q, or RSVP, for example, to return promises from any promissory callback handlers.

For more information on promises in JavaScript, have a look at Promises -- an alternative way to approach asynchronous JavaScript.

Promissory Callbacks

Promises are acceptable return values in the following event handlers. Many of these callbacks can also prevent an associated action from being executed with a false return value (non-promise) or a call to failure() on a returned promise instance (see individual event docs for more details):

  • onCancel
  • onCredentialsExpired
  • onPasteReceived
  • onSubmit
  • onSubmitDelete
  • onValidate
  • onValidateBatch

You are not required to return a promise -- you can simply return false (or nothing). However, there are some instances where you may want to perform some asynchronous work in your callback handler. A promise can be returned from any of the above callbacks if you need to execute some non-blocking task, such as an AJAX request, or asking the user for input via a modal window that does not block the UI thread (such as a Bootstrap modal, or a Bootbox.js dialog box).

qq.Promise API

Note:

Fine Uploader's internal qq.Promise object is not compliant with the A+ specification. If this is a problem for you, feel free to use any compliant promise library of your choice instead.

then (successCallback, failureCallback)

Register callbacks from success and failure. The promise instance that then is called on will pass any values into the provided callbacks. If success or failure have already occurred before these callbacks have been registered, then they will be called immediately after this call has been executed. Each subsequent call to then registers an additional set of callbacks.

Parameters:
Function
successCallback

The function to call when the promise is successfully fulfilled.


Function
failureCallback

The function to call when the promise is unsuccessfully fulfilled.


Returns:
qq.Promise
An instance of a promise.

done (callback)

Register callbacks for success or failure. Invoked when the promise is fulfilled regardless of the result. The promise instance that done is called on will pass any values into the provided callback. Each call to done registers an additional set of callbacks

Parameters:
Function
callback

The function to call when the promise is fulfilled, successful or not.


Returns:
qq.Promise
An instance of a promise.

success (param)

Call this on a promise to indicate success. The parameter value will depend on the situation.

Parameters:
Object
param

The value to pass to the promise's success handler.


Returns:
qq.Promise
An instance of a promise.

failure (param)

Call this on a promise to indicate failure. The parameter value will depend on the situation.

Parameters:
Object
param

The value to pass to the promise's failure handler.


Returns:
qq.Promise
An instance of a promise.

Promissory Options

The showConfirm, showMessage, and showPrompt UI options in Fine Uploader accept promissory return values. This makes it trivial to do work (such as launching a confirmation window and waiting for user input) without blocking the rest of the UI thread (and thus stopping downloads).

Example

Suppose you are overriding a promissory function or callback. For example, suppose you want to override the showPrompt option (function). The default implementation of this function uses window.prompt, which isn't very stylish. You may want to provide a more appropriate prompt dialog for your application. Your implementation, using bootbox for your prompt dialog, might look something like this:

showPrompt: function(message, defaultValue) {
    var promise = new qq.Promise();

    bootbox.prompt("Enter a value", "Cancel", "Confirm", function(result) {
        if (result === null || qq.trimStr(result).length === 0) {
            promise.failure("User canceled prompt dialog or entered an empty string.");
        }
        else {
            promise.success(result);
        }
    }, defaultValue);

    return promise;
}

The bootbox prompt dialog is not blocking, meaning the showPrompt call will return before the user has entered any information. So, you must return a promise that will be updated with the user's response after it is submitted. Fine Uploader will wait for a callback indicating either success or failure, and will then continue executing the original task based on this result. One use of the showPrompt function is to grab a name, from the user, of a pasted image. In this case once the result has been updated on the promise instance, Fine Uploader will proceed to upload the pasted image using the name supplied by the user.