[web-audio-api] Callbacks without Promises (#252)

The following issue was raised by the W3C TAG as part of their [review of the Web Audio API](https://github.com/w3ctag/spec-reviews/blob/master/2013/07/WebAudio.md)

### Callbacks without Promises

A few of the APIs specified use a callback system which can be made Promise-compatible in a straightforward way. For instance, the current definition of `AudioContext::decodeAudioData` is given by:

```
void decodeAudioData(ArrayBuffer audioData,
                     DecodeSuccessCallback successCallback,
                     optional DecodeErrorCallback errorCallback);

```

This can be extended to be Promise-compatible by simply changing the return type:

```
Promise decodeAudioData(ArrayBuffer audioData,
                        optional DecodeSuccessCallback successCallback,
                        optional DecodeErrorCallback errorCallback);

```

This will allow users of these APIs to rely on the same uniform promise interface across this API and many others without changes to the callback style you currently employ. As an implementation detail, the existing success and error callbacks can be recast as though an internal method generated a promise and adds them to the list of listeners:

```
AudioContext.prototype.decodeAudioData = function(data, success, error) {
 var p = __internalDecode(data);
 if (success) {
  p.then(success, error); 
 } 
 return p;
};
```

Note the `successCallback` parameter is now optional.

What's the effect of this? Code can now be written like:

```js
// Wait for 3 samples to decode and then play them simultaneously:
Promise.every(
  ctx.decodeAudioData(buffer1),
  ctx.decodeAudioData(buffer2),
  ctx.decodeAudioData(buffer3)
).then(function(samples) {
  samples.forEach(function(buffer) {
    (new BufferSource(ctx, { buffer: buffer })).start();
  });  
});
```

`OfflineAudioContext` can be similarly improved by vending a `Promise` from `startRendering()` which resolves when `oncomplete`:

```js
offlineContext.startRendering().then(function(renderedBuffer) {
  // ...
});
```

This is both terser and more composable than the current system.


---
Reply to this email directly or view it on GitHub:
https://github.com/WebAudio/web-audio-api/issues/252

Received on Thursday, 17 October 2013 12:25:02 UTC