On Wed, Feb 5, 2014 at 12:34 PM, Brendan Eich <bren...@mozilla.com> wrote:
> Tab Atkins Jr. wrote:
>> (Fixing it does involve magic, or
>> subclassing, but those are things that can be done internally, rather
>> than exposed to authors as terrible API.)
>
> Could you say a bit more? Do you mean APIs that defensively "hand-box" so
> the user doesn't have to, with async map and its overloaded get return
> value?

So, to get a bit more concrete, the ServiceWorker spec introduces
Cache objects, which are asynchronous maps.  When you get/set/etc
anything, you get back a promise for the result.

ServiceWorker also has Response objects, which are what you're
supposed to be putting into the Caches.  Some parts of the API return
Response objects directly, some return promises for Responses.  So
sometimes you'll be storing promises in the Cache.

The APIs for Caches and dealing with responses are designed so that
they work nicely together, acting the same way whether you pass a
Response or a Promise<Response>.  So you can often respond to requests
with a simple "e.respondWith(cache.get('foo'))" and it Just Works®.

So, that part's not affected by the promise change, because the whole
point is that this part of the API unwraps things until it hits a
Response.

But say you wanted to do something a bit more complicated.  For
example, if the cache hits, but the result is a Promise, you might
want to show a throbber until the Promise resolves.  Under the old
consensus, you could do this pretty easily - just do
"cache.get().chain(...)" and then operate on the result.  Under the
new, you can't, because the cache promise won't resolve until after
the response promise resolves.  We can't say "just hand-box", because
it breaks the easy pattern above when you *don't* want to do anything
complicated - you have to .then() it and unbox there.

There are various ways to work around this.  One way is to
auto-handbox: we subclass Promise to CachePromise and hang a .chain()
off of it which receives the actual value you stored in the map, while
.then() silently unboxes and continues flattening as normal.  Another
way is to just guarantee that Cache promises never hand promises to
their callbacks, and ensure that there are alternate ways to check if
a Response is ready yet (maybe just forcing people to more explicitly
track the Response promises directly, and make sure they're synced
with the stuff in the Cache).

~TJ
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to