|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
Found item: why to use eventual scheduling consistentlyhttp://osteele.com/archives/2008/04/minimizing-code-paths-asychronous-code
> Minimizing Code Paths in Asychronous Code > April 20, 2008 in Libraries, Tips | Comments > > Have you ever written a function that looks like this? > > function requestProductDetails(id, k) { > var value = gProductDetailsCache[id]; > if (value) > k(value) > else > ajax.get('/product/'+id, function(data) { > gProductDetailsCache[id] = data; > k(data); > }); > } > > requestProductDetails calls its callback with the product details, > which are stored in a cache. Since it might need to request this > information from the server, it has to “return” it by passing it to > a callback; in order to present a uniform API whether or not the > product is cached, it “returns” the data this way whether it came > from the cache or not. requestProductDetails is intended to be used > this way: > > requestProductDetails(id, function(details) { > infoPanel.setDetails(id, details); > }); > infoPanel.setName(id, gProductNames[id]); > > (I gave infoPanel a somewhat silly API in order to demonstrate a > point. The general pattern is that there’s some computation in the > callback, and some other computation after the call.) > > There’s a subtle problem in this code, which is that two different > code paths run through it. In the cached case, infoPanel.setDetails > is called before infoPanel.setName. In the uncached case (the first > time through), it’s the other way around. If there’s a bug that > causes setDetails to work only after setName has been called, you > may well miss it during casual testing, because it will only trigger > the second time you trigger the code – and once it does trigger, it > will appear intermittently (especially if you have a more > sophisticated cache), and be darned difficult to find. > > I recommend this implementation of requestProductDetails instead. It > makes the inside of the function more complex – and the setTimeout > looks gratuitous – but it makes its outside simpler : > requestProductDetailss callers are much easier to debug. > > function requestProductDetails(id, k) { > var value = gProductDetailsCache[id]; > if (value) > setTimeout(function() { k(value) }, 10); > else > ajax.get('/product/'+id, function(data) { > gProductDetailsCache[id] = data; > k(data); > }); > } > > The general principle here is if a function sometimes has to call > its callback asynchronously, always call it asynchronously, to > minimize the number of possible code paths through the application. -- Kevin Reid <http://switchb.org/kpreid/> _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
| Free embeddable forum powered by Nabble | Forum Help |