Search the Community
Showing results for tags 'promise'.
-
So asynchronous programming is something quite difficult to do in JavaScript, but since we now have Promises and async/await, it's becoming increasingly less complicated. Plus there is no need for "callback hell". So I will assume you understand what Promise.all() is and why it can sometimes be problematic, as it will not wait for all requests to complete and just fails on the first rejected Promise. The following function will still reject on a failed Promise, but the difference being it will wait for all the Promises to complete before resolving or rejecting. If no failure occurred, then the resolved value is the same as Promise.all(), an array of resolved values; otherwise, it returns a completed object (see below for details). Also note that the array might contain empty slots, this is so it's easier to debug which Promise failed in the array, as they're inserted in the same index slot Promise.allComplete = (iterable) => { if (!Array.isArray(iterable)) { throw new TypeError('Invalid argument, expected "iterable" to be an array'); } const completed = { resolved: [], rejected: [], }; const wrapResolutionOrRejection = (type, index) => valueOrReason => (completed[type][index] = valueOrReason); const wrappedIterable = iterable.map((value, index) => Promise.resolve(value) // The rejected wrapper function could be put in the catch, but it's wasteful for our purposes .then(wrapResolutionOrRejection('resolved', index), wrapResolutionOrRejection('rejected', index)) ) return Promise.all(wrappedIterable) .then(() => completed.rejected.length === 0 ? Promise.resolve(completed.resolved) : Promise.reject(completed)); }; // Example const requests = [ createPromise(true, 10), createPromise(false, 10), createPromise(true, 200), createPromise(true, 1000), ]; // Rejects on the first Promise which fails, but if you check in the console, it didn't wait // for the third Promise to successfully complete, as the console log came after the error log was displayed // Promise.all(requests) // .then(values => console.log('Successfully completed', values)) // .catch(err => console.error('Not successfully completed', err)) // "allComplete" is different, in that it will wait for all the Promises to be completed i.e. resolve and reject, // then resolve if all Promises were successful or reject if one Promise failed. // It returns the following data structure: // { // resolved: [...Promises which resolved, and inserted by the associated Promise's index], // rejected: [..Promises which rejected, and inserted by the associated Promise's index], // } Promise.allComplete(requests) .then(completed => console.log('Successfully completed', completed)) .catch(completed => console.log('Not successfully completed', completed)) function createPromise(isResolved, delay) { return new Promise((resolve, reject) => { setTimeout(() => { console.log(`Promise: "${delay}"`); if (isResolved) { resolve(delay); } else { reject(new Error('An unexpected error occurred')); } }, delay); }); }
-
Check if an image actually resolves to a successful HTTP status code e.g. 200 (OK). imageExists returns a promise, so make sure the browser you're using supports promises e.g. Chrome. If not, then you can look at using a polyfill (https://github.com/components/es6-promise) or if you're feeling adventurous, then change the code to use jQuery's deferreds (not recommended). To see it working, copy the code to http://www.es6fiddle.net/ and watch the images either resolve or fail (reject). /*global console, Promise*/ /** * Check if an image is resolvable i.e. returns a HTTP status code that is not 404 * * @param {string} sourceFile An image source file to check * @return {promise} A promise that is resolved/rejected once the image has loaded or a response has been resolved. The source file is passed through */ var imageExists = (function imageExistsModule(document, Promise) { // Append to the global object i.e. window return function imageExists(sourceFile) { if (!sourceFile || !sourceFile.length) { return Promise.reject(sourceFile); } // Create a HTMLImageElement node, but don't insert into the DOM var img = document.createElement('img'); // Set the image element source file img.src = sourceFile; // If the image has already been loaded i.e. cached, then resolve a promise if (img.complete) { return Promise.resolve(sourceFile); } // Return a promise return new Promise(function promise(resolve, reject) { // Create event listeners for when or if the HTMLImageElement is loaded img.addEventListener('error', function errorEvent() { reject(sourceFile); }); img.addEventListener('load', function loadEvent() { resolve(sourceFile); }); }); }; }( document, Promise )); (function example(imageExists, console) { // Check if guinness' thumbnail exists. This returns a promise object imageExists('https://www.autoitscript.com/forum/uploads/profile/photo-thumb-35302.jpg').then(function promiseThen(image) { console.log(image + ' => OKAY'); }).catch(function promiseCatch(image) { console.log(image + ' => FAIL'); }); // Check if a random thumbnail exists. This returns a promise object imageExists('https://www.autoitscript.com/forum/uploads/profile/random-thumb.jpg').then(function promiseThen(image) { console.log(image + ' => OKAY'); }).catch(function promiseCatch(image) { console.log(image + ' => FAIL'); }); }( imageExists, console ));