Promises and Callback support in ml5

ml5.js is heavily inspired by the syntax, patterns and style of the p5.js library. However, there are several differences in how asynchronous operations are handled by ml5.js. ml5.js supports both error-first callbacks and Promises in all methods.

Using Callbacks

In p5.js, callbacks are passed as arguments to functions that often perform some asynchronous operation. For example, p5.js defines the loadJSON() function as the following:

  1. loadJSON('http//example.com/data.json', (results) => {
  2. // Do something with the results
  3. });

Notice that the results from the callback in p5.js are given as the only argument to the function. There is no error argument in the callback.

ml5.js, on the other hand, uses a pattern referred to as an error-first callback:

With this pattern, a callback function is passed to the method as an argument. When the operation either completes or an error is raised, the callback function is called with the Error object (if any) passed as the first argument. If no error was raised, the first argument will be passed as null. Taken from the Node.js documentation

For example if you are using the imageClassifier() method, you will need to construct it in the following way:

  1. // Pass a callback function to constructor
  2. const classifier = ml5.imageClassifier('MobileNet', (err, model) => {
  3. console.log('Model Loaded!');
  4. });
  5. // Make a prediction with the selected image and pass a callback function with two arguments
  6. classifier.predict(image, (err, results) => {
  7. // Check for errors. If no errors, then do something with the results
  8. });

Error first callbacks is a convention common to many JavaScript libraries that we have chosen to adopt. The language JavaScript itself does not enforce this pattern. Keep in mind that most ml5.js methods and functions are asynchronous (machine learning models can take significant amounts of time to process inputs and generate outputs!). You will need to use the error-first callback pattern if you want to use callbacks.

Using Promises

ml5.js also supports Promises. If no callback is provided to any asynchronous function then a Promise is returned.

With Promises, the image classification example can be used in the following way:

  1. // No callback needs to be passed to use Promises.
  2. ml5
  3. .imageClassifier('MobileNet')
  4. .then(classifier => classifier.predict(image))
  5. .then((results) => {
  6. // Do something with the results
  7. });

For some video tutorials about Promises, you can find this Coding Train playlist. There is also a video tutorial about the ES6 arrow notation (\=>).