- From: Nikunj R. Mehta <nikunj.mehta@oracle.com>
- Date: Tue, 22 Dec 2009 19:32:03 -0800
- To: Pablo Castro <Pablo.Castro@microsoft.com>
- Cc: "public-webapps@w3.org" <public-webapps@w3.org>
On Dec 22, 2009, at 5:39 PM, Pablo Castro wrote:
> Whenever we take a callback that's to be called for each item in a
> set (e.g. with a .forEach(callback) pattern), we need a way to
> indicate the system whether it's ok to move to the next row and
> invoke the next callback or not. Otherwise, in scenarios where the
> callback itself performs an operation that doesn't finish
> immediately (such as another database async call) the system will
> keep queuing up top-level callbacks, which in turn may queue up more
> callbacks as part of its implementation, and execution will be in
> "some order" that's very hard to predict at best.
>
> This comes up in several contexts. Applications will often need to
> scan more than one object store in coordination. Query processors
> will also need this when implementing physical operators for joins
> and such. A different context would be a system that needs to submit
> an HTTP request per row, where you may want to use an XmlHttpRequest
> and unwind after calling open. While the HTTP request is in flight
> you don't want to move to the next
>
> In most cases one of the key aspects is that we need separate
> components to work cooperatively as they pull rows from one or
> multiple scans, and there needs to be a way of controlling the
> advance of cursors through the rows.
>
> We would like to introduce "pause" and "resume" functions for scans
> to support this. Since there is no obvious place to put this right
> now, we could introduce an "iterator" object that can be used to
> control things related to the current state of the iteration as of
> when the callback happens, or maybe this is the cursor itself.
>
> The resulting code would look like this (the example uses the single-
> async-level pattern we're playing around, but these two are actually
> independent things):
>
> async_db.forEachObjectInStore("people", function(person, iteration) {
> iteration.pause(); // we won't be done with 'person' until later...
> var request = async_db.getFromStore("people", person.managerId);
> request.onsuccess = function() {
> var manager = request.result;
> // Do something with both 'person' and 'manager', and now we're
> ready to process the next person.
> iteration.resume();
> };
> });
>
> The nice thing about adding these as methods on the side is that
> it's completely out of sight in simple scenarios where you may be
> just scanning to build some HTML for example. Only if you're doing
> multiple coordinated, async tasks you need to know about these
> functions.
>
> Regards,
> -pablo
>
The proposed WD can do what you want. You would write the following
code for async processing, even though the solution is not the easiest
to follow:
async_db.request.onsuccess = function() {
var people = async_db.request.result;
people.request.onsuccess = function() {
var cursor = people.request.result;
var eachPerson = function() {
var person = cursor.value;
cursor.request.onsuccess = eachPerson;
people.request.onsuccess = function() {
var manager = people.request.result;
// do something with both person and manager
cursor.continue();
}
cursor.request.onerror = function () {
// do what you will when all the people have been processed
}
people.get(person.managerId);
}
eachPerson();
}
people.openCursor();
}
async_db.openObjectStore("people");
It is difficult to follow the logic above, so I will also give a
synchronous example:
var people = async_db.openObjectStore('people');
var cursor = people.openCursor();
if (cursor)
do {
var person = cursor.value;
var manager = people.get(person.managerId);
// do something with person and manager
} while (cursor.continue());
// we are done with all the people
As I said earlier, there is something to be said about the
comprehensibility of the asynchronous code above, but let's look at
the expressive power separately from ease of programming.
Nikunj
http://o-micron.blogspot.com
Received on Wednesday, 23 December 2009 04:06:46 UTC