Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>My suggestions to get this working with Q.js are below. The key is that anytime you want to do something asynchronously, you should return a promise, and once the task is completed you should resolve that promise. That allows the callers of the function to listen for the task to be completed and then do something else.</p> <p>As before, I have commented my changes with <code>// ***</code>. Let me know if you have any further questions.</p> <pre><code> function traverseFiles() { // *** Create an array to hold our promises var promises = [ ]; for (var i=0, l=pages.length; i&lt;l; i++) { // *** Store the promise returned by getSizeSettingsFromPage in a variable promise = getSizeSettingsFromPage(pages[i]); promise.then(function(values) { var width = values[0], height = values[1], filename = values[2]; // *** When the promise is resolved, call calculateRatio calculateRatio(width, height, filename); }); // *** Add the promise returned by getSizeSettingsFromPage to the array promises.push(promise); } // *** Call checkWhenReady after all promises have been resolved Q.all(promises).then(checkWhenReady); } function getSizeSettingsFromPage(file) { // *** Create a Deferred var deferred = Q.defer(); reader = new FileReader(); reader.onload = function(evt) { var image = new Image(); image.onload = function(evt) { var width = this.width; var height = this.height; var filename = file.name; // *** Resolve the Deferred deferred.resolve([ width, height, filename ]); }; image.src = evt.target.result; }; reader.readAsDataURL(file); // *** Return a Promise return deferred.promise; } </code></pre> <hr> <h2>Edit</h2> <p><code>defer</code> creates a <strong>Deferred</strong>, which contains two parts, a <code>promise</code> and the <code>resolve</code> function. The <code>promise</code> is returned by <code>getSizeSettingsFromPage</code>. Basically returning a promise is a way for a function to say "I'll get back to you later." Once the function has completed it's task (in this case once the <code>image.onload</code> event has fired) the <code>resolve</code> function is used to resolve the promise. That indicates to anything waiting on the promise that the task has been completed.</p> <p>Here's a simpler example:</p> <pre><code>function addAsync(a, b) { var deferred = Q.defer(); // Wait 2 seconds and then add a + b setTimeout(function() { deferred.resolve(a + b); }, 2000); return deferred.promise; } addAsync(3, 4).then(function(result) { console.log(result); }); // logs 7 after 2 seconds </code></pre> <p>The <code>addAsync</code> function adds two numbers but it waits 2 seconds before adding them. Since it's asynchronous, it returns a promise (<code>deferred.promse</code>) and resolves the promise after the 2 second wait (<code>deferred.resolve</code>). The <code>then</code> method can be called on a promise and passed a callback function to be executed after the promise has been resolved. The callback function is passed in the resolution value of the promise.</p> <p>In your case, we had an array of promises and we needed to wait for <em>all</em> of them to be done before executing a function, so we used <strong>Q.all</strong>. Here's an example:</p> <pre><code>function addAsync(a, b) { var deferred = Q.defer(); // Wait 2 seconds and then add a + b setTimeout(function() { deferred.resolve(a + b); }, 2000); return deferred.promise; } Q.all([ addAsync(1, 1), addAsync(2, 2), addAsync(3, 3) ]).spread(function(result1, result2, result3) { console.log(result1, result2, result3); }); // logs "2 4 6" after approximately 2 seconds </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload