Javascript uses return value in another function

What I want to achieve is to use the return value of the "previewfile" function as a progress bar for the "readfiles" function. But this should be after executing "image.onload" , since there I need returnThis to set to true. I have researched several things on Google and Stackoverflow on this issue and callbacks / deferred objects in general, but I cannot plunge into how to use this in this situation.

In the image upload section, I have the following constellation:

function previewfile(file, tests, acceptedTypes, holder) { var returnThis = false; if (tests.filereader === true && acceptedTypes[file.type] === true) { var reader = new FileReader(); reader.onload = function (event) { var image = new Image(); image.onload = function() { var testimage = new Image(); testimage.src = $(this).attr('src'); var widthOfImage = testimage.width; var heightOfImage = testimage.height; if (!checkImageDimensions(widthOfImage, heightOfImage)) { // do stuff } else { returnThis = true; } }; image.src = event.target.result; holder.appendChild(image); }; reader.readAsDataURL(file); } else { // do other stuff } return returnThis; } function readfiles(files, tests, acceptedTypes, holder, progress) { var uploadNow = previewfile(files[0], tests, acceptedTypes, holder); if (uploadNow === true) { // do stuff } } else { // do other stuff } } 
+5
source share
3 answers

Using FelixKling and kallehj, this is a working solution (with callback):

 // important function previewfile(file, tests, acceptedTypes, holder, callback) { var returnThis = false; if (tests.filereader === true && acceptedTypes[file.type] === true) { var reader = new FileReader(); reader.onload = function (event) { var image = new Image(); image.onload = function() { var testimage = new Image(); testimage.src = $(this).attr('src'); var widthOfImage = testimage.width; var heightOfImage = testimage.height; if (!checkImageDimensions(widthOfImage, heightOfImage)) { // do stuff } else { returnThis = true; } callback(returnThis); // important }; image.src = event.target.result; holder.appendChild(image); }; reader.readAsDataURL(file); } else { callback(returnThis); // important } } function readfiles(files, tests, acceptedTypes, holder, progress) { // important previewfile(files[0], tests, acceptedTypes, holder, function (uploadNow) { if (uploadNow === true) { // do stuff } } else { // do other stuff } } }); 
+1
source

I would go with something like this

 function readfiles(files, tests, acceptedTypes, holder, progress) { previewfile(files[0], tests, acceptedTypes, holder, function(value){ if (uploadNow === true){ // do stuff } else { // do other stuff } }); } function previewfile(file, tests, acceptedTypes, holder, callback) { ... callback(returnValue); //instead of return } 
+2
source

Since previewfile() relies on asynchronous activity, it itself is asynchronous. Thus, he cannot reliably return a value, but he can return a promise.

As others have pointed out, previewfile() can be written to accept a callback, avoiding the need for a promise. However, if you want to receive a promise, here is one (of course, not the only one).

 function previewfile(file, tests, acceptedTypes, holder) { if(tests.filereader === true && acceptedTypes[file.type] === true) { var reader = new FileReader(), image; var promise_a = $.Deferred(function(dfrd) { reader.onload = function(event) { image.attr('src', event.target.result).appendTo(holder); dfrd.resolve(); }; reader.onerror = function() { dfrd.reject('fileReader error'); }; }).promise(); var promise_b = $.Deferred(function(dfrd) { image = $("<img/>").on('load', function() { var widthOfImage = image.width; var heightOfImage = image.height; if (checkImageDimensions(widthOfImage, heightOfImage)) { dfrd.resolve(); } else { //do stuff dfrd.reject('image loaded but dimensions did not check out'); } }).error(function() { dfrd.reject('image did not load'); }); }).promise(); reader.readAsDataURL(file); return $.when(promise_a, promise_b); } else { // do other stuff // Also return a promise here, even if no async is involved. } } 

readfiles() can now be written as follows:

 function readfiles(files, tests, acceptedTypes, holder, progress) { return previewfile(files[0], tests, acceptedTypes, holder).then(function() { // do stuff }).then(null, function(reason) { console.log(reason);// or display to the user in the DOM. // do other stuff }); } 

The advantage of a promise-based solution is perhaps not so much in successful management as in managing errors. Notice how one handler reports several different types of errors.

+1
source

Source: https://habr.com/ru/post/1200412/


All Articles