Re: [whatwg] Promise-vending loaded() ready() methods on various elements
Thanks, updated my code examples to reflect this On 14 March 2014 23:57, Boris Zbarsky bzbar...@mit.edu wrote: On 3/14/14 6:04 PM, Jake Archibald wrote: Any guarantees of ordering if fully cached? I believe no. -Boris
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
On 15 March 2014 00:31, Kyle Simpson get...@gmail.com wrote: I'd say the first syntax is a bit verbose for what I was dreaming 4 years ago when I started asking for a simple script preloading mechanism, but it's just this side of acceptable. If we have to take the second approach, I say that's unacceptably more verbose/complex and falls short of my opinion of everything we need for sane versitile dependency loading. It's everything we need but perhaps not everything we desire. Last time we went round with script loading the proposal for high-level dependency declaration got weighed down by use-cases that should have been left to lower level primitives. These are the lower level bits, something higher level is still possible. For legacy-free project, modules + promises for non-script assets are the answer. I updated my examples to deal with no guarantees of script order. A couple of forEachs were turned to reduces, that was it.
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
On 15 March 2014 00:35, Kyle Simpson get...@gmail.com wrote: there's a seemingly implicit requirement that we have to get both ES6 promises and DOM promises to land for these suggested approaches to work. ES6 promises are already in Chrome stable, they're on the route to stable in Firefox. Promises will only be absent in browsers that have no intention of being ES6 compliant. At one point the conversation shifted towards ServiceWorker as being the answer. It isn't. Network requests are still async in a ServiceWorker world. You can use it to prepare caches and respond to requests with it, but if your response strategy is try cache, then network, then fallback link rel=preload can still give you a performance benefit by going through that process sooner. Why isn't putting preloading into existing script elements (whether exposed by events or by promises) better than splitting it out into a separate element (link rel=preload) and requiring a third mechanism (promises) to wire them up? Preloading is important for more than just scripts, making it a script-only feature is restrictive. Preloading is useful for images, audio sprites, initial JSON requests etc etc. Is there any chance we could take a fresh look at the earlier proposals (putting both preloading and loading/exec into script), and perhaps freshen them up with promises instead of events? Going back to the proposal in the OP, this isn't intended as the full solution to the previous script loading thread(s). All new async/failure JS DOM APIs use promises, but our existing APIs need this love too. Not just for scripts, but for stylesheets, images, xhr and mixing all those things together with Promise.all. link rel=preload is a separate effort, but I wanted to show the flexibility you get with these components and add to the use-cases. Yes, the script loading stuff can be revisited, but it's a separate effort to these promise-vending methods link rel=preload.
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
As I noted above, what we need to know (and I guess we need to know this from all browsers) if there's a *guarantee* of a-b-c execution order (even if all 3 are executing async) I don't believe there is such a guarantee, unless the spec spells it out explicitly. The `async=false` stuff in the spec talks about dynamically loaded (not parser loaded) scripts going into a queue so they are downloaded in parallel, but executed in request-order from the queue. So, in my aforementioned `execScript(..)` function, if it also set `s.async = false`, I believe that would opt all of the scripts into the async queue. function execScript(l) { var s = document.createElement(script); s.async = false; // -- insert this to get ordered-async s.src = l.href; document.head.appendChild(s); return s.loaded(); } Even though all of them would, at that point, be strictly loading from cache, it should still have the effect of ensuring they execute strictly in a-b-c order, correct? - One downside to this is that there were use-cases where the single queue that this spec mechanism created were not sufficient, such as loading a group of scripts for widget A and another independent group of scripts widget B, and not wanting A or B to block the other. If all of those scripts were set with `async=false` and thus all put in that single queue, widget A's scripts could block widget B's scripts, which sorta fails that use-case. However, it would probably only be a slight delay, as you wouldn't (in the previously mentioned code pattern) add the script elements to the DOM (and thus the queue) until after all the link rel=preload's had finished loading, so it would only be parsing/execution that blocked, not downloading. Execution is already an implicit blocking, as the engine can only run one script at a time, so actually, it's just a concern of potential parsing blocking other parsing. The question is whether `async=false` scripts in the queue can be parsed in parallel (unblocked from each other) on the background threads, as you said, or whether being in that async=false queue means that both parsing and execution happen in order, and thus could cause long parsing of widget A's scripts from blocking parsing of widget B's scripts? However you slice it, I think it would cause *some* delays between widget A and B (aka, not totally independent), but it would in general be far less delays than what we have currently, which is that downloading blocks in that queue. So that seems like a big (if not complete) win. :) --Kyle
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
I'd say the first syntax is a bit verbose for what I was dreaming 4 years ago when I started asking for a simple script preloading mechanism, but it's just this side of acceptable. If we have to take the second approach, I say that's unacceptably more verbose/complex and falls short of my opinion of everything we need for sane versitile dependency loading. It's everything we need but perhaps not everything we desire. If everything we need was the only standard, then the proposals we had discussed years ago should have been pushed through, years ago. Those discussions were bogged down because, as you say in the next sentence (quoted below), there were some on this list who insisted that mechanisms which couldn't be markup-only were insufficient, not just undesirable. For my part, I hope our current discussion thread is signaling a shift from the previous dogmatism (on all sides). Last time we went round with script loading the proposal for high-level dependency declaration got weighed down by use-cases that should have been left to lower level primitives. These are the lower level bits, something higher level is still possible. For legacy-free project, modules + promises for non-script assets are the answer. It was never a priority of *mine* to support zero-script-loader capability. I think, and always have, that script loaders are the place where logic for anything beyond straight-forward loading *should* occur. But there was clearly a LOT of noise in the past whenever I pointed out advanced use-cases, and this noise led to suggestions about markup-only (zero-script-loader) mechanisms for handling all or most of the use-cases in a way that theoretically could eliminate any need for script loaders. Recall all the discussions of `depends='...'` attributes being able to annotate one script's dependencies on another script or scripts? I was only trying to call out the fact that there had been a very clear intention in the past to get some silver-bullet solution that implies zero-script-loader, and what we're currently discussing (.loaded() promises) is NOT that. If we are, at this point in the years-long arc of discussion, ready to set that requirement aside, and admit that markup capabilities (link rel=preload and script) are for the straight linear a-b-c use-cases, and that the more sophisticated use-cases (like dynamic loading, independent widgets, etc etc) require logic that belongs in some form of script loader (whether a lib or a set of inline boilerplate code) that handles all the promises-negotiation, then I'm fine with that approach. I say fine relatively, because I don't really like the ugliness if we have to ensure order ourselves (maybe we don't!?), but it's not a deal-breaker either way. --Kyle
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
On 3/15/14 11:36 AM, Kyle Simpson wrote: The `async=false` stuff in the spec talks about dynamically loaded (not parser loaded) scripts going into a queue so they are downloaded in parallel, but executed in request-order from the queue. Then those are guaranteed to be serialized. The question is whether `async=false` scripts in the queue can be parsed in parallel Nothing prevents that, as long as make sure you don't execute them as soon as the parse is done if the previous scripts haven't executed yet. -Boris
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
This, along with Ilya's proposed link rel=preload ( https://docs.google.com/a/google.com/document/d/1HeTVglnZHD_mGSaID1gUZPqLAa1lXWObV-Zkx6q_HF4/edit#heading=h.x6lyw2ttub69), and JavaScript modules ( https://github.com/dherman/web-modules/blob/master/module-tag/explainer.md) gives us everything we need for sane versitile dependency loading. Problem: Initialising an app on document ready, but also waiting for a particular stylesheet to apply Solution: https://gist.github.com/jakearchibald/955e4f014a264b1f50c4 Problem: Initialising an app after a non-module script Solution: https://gist.github.com/jakearchibald/000ab94ad9fa5cfe62a8 Taking the more complex use-cases from http://lists.w3.org/Archives/Public/public-whatwg-archive/2013Aug/0277.html… [Use-case Q:] Want to avoid executing a social-media script until the user give some intent, although the script should be preloaded. Solution: https://gist.github.com/jakearchibald/dd25f0f2cf47bf2ab93e [Use-case S:] One plugin wants to execute A.js and B.js in order following an interaction. Another wants to load A.js then C.js D.js in either order. A.js should only execute once. Scripts aren't written as modules and out of developer's control. Solution: https://gist.github.com/jakearchibald/120309d88a8bf025e92e [Use-case T:] Preload 2 scripts, execute one or the other on particular interactions Solution: Same as Q. [Use-case U:] A.js, B.js, C.js - load them in parallel, execute in order, only execute when all have preloaded. Solution: https://gist.github.com/jakearchibald/5898e3a4fce62579d75b [Use-case V:] As U, but don't need to wait for all before executing. Stop executing if any script fails to load. Solution: https://gist.github.com/jakearchibald/ea7583d50bf3b46395e0 [Use-case W:] As W, but break on execution errors Solution: https://gist.github.com/jakearchibald/1b12a0e5414a69d9350f [Use-case X:] Loading non-js dependencies Solution: Use XHR + preload for prescanner [Use-case Y:] Some libraries may need async initialization. Solution: These libs should provide a ready promise. [Use-case Z:] Wait on existence of particular element before executing script Solution: Either put the script that handles script loading after the element in question, or use mutation observers Cheers, Jake. On 12 March 2014 14:27, Jake Archibald jaffathec...@gmail.com wrote: On 12 March 2014 14:17, Domenic Denicola dome...@domenicdenicola.comwrote: var img = document.createElement(img); var promise1 = img.loaded(); img.src = foo.png; var promise2 = img.loaded(); // (1) will promise1 be immediately fulfilled, since img has about:blank or similar loaded already? // (2) or will promise1 and promise2 fulfill at the same time, since promise1 waits until a src appears? // (3) or will promise1 be rejected with AbortError, similar to Jake's previous case? // (4) or it could be rejected with an InvalidStateError saying you can't wait for the loading of a non-src'ed image. Here (1), (3), and (4) seem to encourage a consistent model of always ask for loaded() promises after setting src, otherwise it won't work. It's (2) that's problematic as if that's the case then asking for loaded() promises before setting src sometimes works, but usually doesn't. This is a very good point, and I'd say (4). Lets say you didn't change the src: (1) Means the promise would reject with an EncodingError as it isn't a valid image format (2) Would remain unresolved (3) N/A (4) Reject with InvalidStateError The consistency makes me like (4) the most.
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
This, along with Ilya's proposed link rel=preload ( https://docs.google.com/a/google.com/document/d/1HeTVglnZHD_mGSaID1gUZPqLAa1lXWObV-Zkx6q_HF4/edit#heading=h.x6lyw2ttub69), and JavaScript modules ( https://github.com/dherman/web-modules/blob/master/module-tag/explainer.md) gives us everything we need for sane versitile dependency loading. Is link rel=preload going to fire this loaded event after it finishes pre-loading but BEFORE it executes (or, rather, BEFORE because it doesn't execute them at all)? Because for script, the load event fires only after it has loaded AND executed, which is of course too late for many of the more advanced use-cases below. If you want to dynamically *preload* scripts (that is, you don't have link rel=preload tags in your initial page markup) later on in the lifetime of the page, is the story basically like this? function preloadScript(src) { var l = document.createElement(link); l.rel = preload; l.href = src; document.head.appendChild(l); return l.loaded(); } function execScript(l) { var s = document.createElement(script); s.src = l.href; document.head.appendChild(s); return s.loaded(); } Promise.all( preloadScript(a.js), preloadScript(b.js), preloadScript(c.js) ) .then(function(links){ return Promise.all.apply(null,links.map(execScript)); }) .then(function(){ alert(All scripts loaded and executed); }); So, if that's how we think this would work, we need to understand how the `execScript(..)` logic is going to be treated. Is creating a script element dynamically and inserting it going to make sure that it either: a. executes sync b. executes async, but a.js will *definitely* execute before b.js, which will *definitely* execute before c.js. In other words, is there any possibility that it won't execute in order a - b - c in the above code? If so, do/don't we have to be more complex, like? Promise.all( preloadScript(a.js), preloadScript(b.js), preloadScript(c.js) ) .then(function(links){ var chain; links = links.forEach(function(link){ if (!chain) chain = execScript(link); else chain = chain.then(function(){ return execScript(link); }); }); return chain; }) .then(function(){ alert(All scripts loaded and executed); }); --Kyle
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
On 14 March 2014 20:10, Kyle Simpson get...@gmail.com wrote: Is link rel=preload going to fire this loaded event after it finishes pre-loading but BEFORE it executes (or, rather, BEFORE because it doesn't execute them at all)? link rel=preload doesn't execute (you can use it to preload anything), so loaded() fulfills before execution. With script loaded() fulfills after execution. If you want to dynamically *preload* scripts (that is, you don't have link rel=preload tags in your initial page markup) later on in the lifetime of the page, is the story basically like this? Promise.all( preloadScript(a.js), preloadScript(b.js), preloadScript(c.js) ) .then(function(links){ return Promise.all.apply(null,links.map(execScript)); }) .then(function(){ alert(All scripts loaded and executed); }); So, if that's how we think this would work, we need to understand how the `execScript(..)` logic is going to be treated. Is creating a script element dynamically and inserting it going to make sure that it either: a. executes sync b. executes async, but a.js will *definitely* execute before b.js, which will *definitely* execute before c.js. I'm hoping a, but you tell me. Do you know what browsers do with a fully cached script? Is there consistency there? If not, yeah, you'll have to create a chain. (btw, Promise.all takes an array, which nicely avoids the .apply stuff) Jake.
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
On 3/14/14 5:03 PM, Jake Archibald wrote: Do you know what browsers do with a fully cached script? script src=url is always executed async when inserted into the DOM, cached or not. scripttext/script is executed sync. -Boris
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
On 14 March 2014 21:05, Boris Zbarsky bzbar...@mit.edu wrote: On 3/14/14 5:03 PM, Jake Archibald wrote: Do you know what browsers do with a fully cached script? script src=url is always executed async when inserted into the DOM, cached or not. Any guarantees of ordering if fully cached? If not, yeah, async=false or chain via .loaded is the way to go.
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
On 3/14/14 6:04 PM, Jake Archibald wrote: Any guarantees of ordering if fully cached? I believe no. -Boris
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
So, if that's how we think this would work, we need to understand how the `execScript(..)` logic is going to be treated. Is creating a script element dynamically and inserting it going to make sure that it either: a. executes sync b. executes async, but a.js will *definitely* execute before b.js, which will *definitely* execute before c.js. I'm hoping a, but you tell me. Do you know what browsers do with a fully cached script? Is there consistency there? If not, yeah, you'll have to create a chain. Regardless of (a) or (b), the simpler Promise approach (my first snippet) is sufficient, if and only if a-b-c is the *guaranteed* execution order. That's the important part. If there's a chance the browser might do b-a-c (even if all were equally ready in the cache), then the pattern goes fubar and the uglier second syntax is required. I'd say the first syntax is a bit verbose for what I was dreaming 4 years ago when I started asking for a simple script preloading mechanism, but it's just this side of acceptable. If we have to take the second approach, I say that's unacceptably more verbose/complex and falls short of my opinion of everything we need for sane versitile dependency loading. Do you know what browsers do with a fully cached script? script src=url is always executed async when inserted into the DOM, cached or not. Boris- As I noted above, what we need to know (and I guess we need to know this from all browsers) if there's a *guarantee* of a-b-c execution order (even if all 3 are executing async) when they are added to the DOM in that order and all 3 are guaranteed preloaded first, by the link rel=preload tag usage? Is there ever a case where some other execution order than a-b-c would happen? --Kyle
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
I'd also like to make the observation that putting link rel=preload.loaded() together with script.loaded(), and indeed needing a promise mechanism to wire it altogether, is a fair bit more complicated than the initial proposals for script preloading use-cases from the earlier threads over the last few years of this list. For one, we're talking about twice as many DOM elements. For another, there's a seemingly implicit requirement that we have to get both ES6 promises and DOM promises to land for these suggested approaches to work. I don't know if that's already a guarantee or if there are some browsers which are possibly going to land DOM promises before ES6 promises? If so, ES6 promises become the long pole, which isn't ideal. Lastly, I'd observe that many of the arguments against the original/previous script preloading proposals were heavily weighted towards we don't like script loaders, we want to make them obsolete, we need simple enough (declarative markup) mechanisms for that stuff so as to make script loaders pointless… At one point the conversation shifted towards ServiceWorker as being the answer. When we explored the use cases, it was my impression there was still a fair amount of non-trivial code logic to perform these different loading cases with SW, which means for the general user to take advantage of such use-cases, they're almost certainly going to need some library to do it. I can't imagine most end-users writing the previously-suggested ServiceWorker code, and I'm having a hard time believing that they'd alternatively be writing this newly suggested promises-based loading logic all over their pages. In either case, I think for many of the use-cases to be handled, most general users will need to use some script-loader lib. So, if this .loaded() DOM promises thing isn't the silver bullet that gets us to no script loader utopia, then I don't see why it's demonstrably better than the simpler earlier proposals. Moreover, the earlier proposals relied on the browser having logic built-in to handle stuff like download in parallel, execute serially, which made their interface (the surface area users needed to work with) much less than either the Promises here or the ServiceWorker before. What you're implicitly suggesting with both sets of suggestions is, let's make the user do the more complicated logic to wire things together, instead of the browser doing it. Why? Why isn't putting preloading into existing script elements (whether exposed by events or by promises) better than splitting it out into a separate element (link rel=preload) and requiring a third mechanism (promises) to wire them up? Is there any chance we could take a fresh look at the earlier proposals (putting both preloading and loading/exec into script), and perhaps freshen them up with promises instead of events? --Kyle
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
There is no such thing as DOM promises. From: Kyle Simpsonmailto:get...@gmail.com Sent: 3/14/2014 20:35 To: whatwg@lists.whatwg.orgmailto:whatwg@lists.whatwg.org Subject: Re: [whatwg] Promise-vending loaded() ready() methods on various elements I'd also like to make the observation that putting link rel=preload.loaded() together with script.loaded(), and indeed needing a promise mechanism to wire it altogether, is a fair bit more complicated than the initial proposals for script preloading use-cases from the earlier threads over the last few years of this list. For one, we're talking about twice as many DOM elements. For another, there's a seemingly implicit requirement that we have to get both ES6 promises and DOM promises to land for these suggested approaches to work. I don't know if that's already a guarantee or if there are some browsers which are possibly going to land DOM promises before ES6 promises? If so, ES6 promises become the long pole, which isn't ideal. Lastly, I'd observe that many of the arguments against the original/previous script preloading proposals were heavily weighted towards we don't like script loaders, we want to make them obsolete, we need simple enough (declarative markup) mechanisms for that stuff so as to make script loaders pointless… At one point the conversation shifted towards ServiceWorker as being the answer. When we explored the use cases, it was my impression there was still a fair amount of non-trivial code logic to perform these different loading cases with SW, which means for the general user to take advantage of such use-cases, they're almost certainly going to need some library to do it. I can't imagine most end-users writing the previously-suggested ServiceWorker code, and I'm having a hard time believing that they'd alternatively be writing this newly suggested promises-based loading logic all over their pages. In either case, I think for many of the use-cases to be handled, most general users will need to use some script-loader lib. So, if this .loaded() DOM promises thing isn't the silver bullet that gets us to no script loader utopia, then I don't see why it's demonstrably better than the simpler earlier proposals. Moreover, the earlier proposals relied on the browser having logic built-in to handle stuff like download in parallel, execute serially, which made their interface (the surface area users needed to work with) much less than either the Promises here or the ServiceWorker before. What you're implicitly suggesting with both sets of suggestions is, let's make the user do the more complicated logic to wire things together, instead of the browser doing it. Why? Why isn't putting preloading into existing script elements (whether exposed by events or by promises) better than splitting it out into a separate element (link rel=preload) and requiring a third mechanism (promises) to wire them up? Is there any chance we could take a fresh look at the earlier proposals (putting both preloading and loading/exec into script), and perhaps freshen them up with promises instead of events? --Kyle
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
On 3/14/14 8:31 PM, Kyle Simpson wrote: As I noted above, what we need to know (and I guess we need to know this from all browsers) if there's a *guarantee* of a-b-c execution order (even if all 3 are executing async) I don't believe there is such a guarantee, unless the spec spells it out explicitly. For async scripts, Gecko, does the initial script parse+compile on a random background thread from a threadpool, and if there is not an explicit dependency between the scripts (which I _think_ is only there for parser-inserted scripts) then the script will simply run whenever that script's background parse thread finishes. -Boris
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
On 3/12/14 7:23 AM, Jake Archibald wrote: == img/link/script/document/iframe .loaded() == If the element hasn't loaded or is loading, vend a promise that resolves/rejects on its load/error event. If the element has fired load/error and isn't loading due to a source change, vend a resolved/rejected promise. This seems fundamentally racy, no? In particular, the fact that a new load can start (and maybe finish?) between the loaded() call and the time when the promise notifies its consumers is a bit worrying. I agree that we need something better than the current easy-to-miss load event setup here, though -Boris
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
On 12 March 2014 13:15, Boris Zbarsky bzbar...@mit.edu wrote: On 3/12/14 7:23 AM, Jake Archibald wrote: == img/link/script/document/iframe .loaded() == If the element hasn't loaded or is loading, vend a promise that resolves/rejects on its load/error event. If the element has fired load/error and isn't loading due to a source change, vend a resolved/rejected promise. This seems fundamentally racy, no? In particular, the fact that a new load can start (and maybe finish?) between the loaded() call and the time when the promise notifies its consumers is a bit worrying. You're right, I was short on detail for that case. img.src = foo; var promise1 = img.loaded(); img.src = bar; I expect promise1 to reject with an AbortError.
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
On 3/12/14 9:32 AM, Jake Archibald wrote: You're right, I was short on detail for that case. img.src = foo; var promise1 = img.loaded(); img.src = bar; I expect promise1 to reject with an AbortError. No, the case I'm worried about is when the first load has already finished, you call loaded(), get a promise (already resolved), and then a new load starts, and maybe finishes, before the promise has notified things. So more like this: var promise1; img.onload = function() { promise1 = img.loaded(); img.onload = null; img.src = bar; }; img.src = foo; I realize no one would write actual code like this; the real-life use case I'm worried about would be more like this: // img is already loaded sometimes // Would like to observe a new load var promise1 = img.loaded(); // oops! This will be pre-resolved if // we were already loaded, but otherwise // will resolve with the new load we're // about to start. img.src = bar; Is my concern making sense? Images are particularly pernicious here because img.src = bar might synchronously finish the load, even if it fires the load event async. -Boris
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
From: whatwg-boun...@lists.whatwg.org [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of Boris Zbarsky // img is already loaded sometimes // Would like to observe a new load var promise1 = img.loaded(); // oops! This will be pre-resolved if // we were already loaded, but otherwise // will resolve with the new load we're // about to start. img.src = bar; Is my concern making sense? It's interesting, because this is exactly the *wrong* type of code to write with promises; whereas it's the *right* type of code for events. With promises you should only ask for the loaded promise *after* setting `src`; anything you retrieve before that represents a previous load. Except, I suppose, for the base-case of images with no src, transitioning to having an src? Or are they considered to have e.g. loaded `about:blank` already? I.e. what should this do? var img = document.createElement(img); var promise1 = img.loaded(); img.src = foo.png; var promise2 = img.loaded(); // (1) will promise1 be immediately fulfilled, since img has about:blank or similar loaded already? // (2) or will promise1 and promise2 fulfill at the same time, since promise1 waits until a src appears? // (3) or will promise1 be rejected with AbortError, similar to Jake's previous case? // (4) or it could be rejected with an InvalidStateError saying you can't wait for the loading of a non-src'ed image. Here (1), (3), and (4) seem to encourage a consistent model of always ask for loaded() promises after setting src, otherwise it won't work. It's (2) that's problematic as if that's the case then asking for loaded() promises before setting src sometimes works, but usually doesn't.
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
On 3/12/14 10:17 AM, Domenic Denicola wrote: With promises you should only ask for the loaded promise *after* setting `src` Ah, fair. I'd been hoping we could get away without having to very carefully order the code, but I'm just not seeing a way to do that. Except, I suppose, for the base-case of images with no src, transitioning to having an src? Or are they considered to have e.g. loaded `about:blank` already? They're not right now. // (2) or will promise1 and promise2 fulfill at the same time, since promise1 waits until a src appears? This is what will happen in current implementations if nothing special is done. // (4) or it could be rejected with an InvalidStateError saying you can't wait for the loading of a non-src'ed image. This would make some sense, yes. -Boris
Re: [whatwg] Promise-vending loaded() ready() methods on various elements
On 12 March 2014 14:17, Domenic Denicola dome...@domenicdenicola.comwrote: var img = document.createElement(img); var promise1 = img.loaded(); img.src = foo.png; var promise2 = img.loaded(); // (1) will promise1 be immediately fulfilled, since img has about:blank or similar loaded already? // (2) or will promise1 and promise2 fulfill at the same time, since promise1 waits until a src appears? // (3) or will promise1 be rejected with AbortError, similar to Jake's previous case? // (4) or it could be rejected with an InvalidStateError saying you can't wait for the loading of a non-src'ed image. Here (1), (3), and (4) seem to encourage a consistent model of always ask for loaded() promises after setting src, otherwise it won't work. It's (2) that's problematic as if that's the case then asking for loaded() promises before setting src sometimes works, but usually doesn't. This is a very good point, and I'd say (4). Lets say you didn't change the src: (1) Means the promise would reject with an EncodingError as it isn't a valid image format (2) Would remain unresolved (3) N/A (4) Reject with InvalidStateError The consistency makes me like (4) the most.