The project ran into a situation where I uploaded multiple image previews at once. I was transferring images to Base64 previews, but the problem was that the asynchronous stuff was a bit of a pitfall. The code base will not be detailed, want to see the base can go to the h5 upload file I wrote – preview

For example: The order and size of the images we want to upload at one time is shown below.

html

<input type="file" multiple="multiple" class="upload_file"/><br/><br/>
<a href="javascript:;" class="upload_btn"> upload </a> <div class="box"></div>
Copy the code

js

Var arr_files =[], upload_file = document.querySelector('.upload_file'),// Image upload text box= document.querySelector('.box'Upload_btn = document.querySelector('.upload_btn'); // Upload button upload_file. AddEventListener ('change'.function(e){ select.base64(this.files); //base64 preview}); // Preview the imagefunction preview(base64_arr){
    for(var i=0,b=base64_arr.length; i<b; i++){ var img =document.createElement('img');
    	img.src=base64_arr[i].base64;
    	img.style.cssText="width:100px;"box.appendChild(img); }}Copy the code

The key codes are as follows

select=(function(){
    var way ={
        base64:base64,
        add:function(key,callback){ this[key]=callback; }// Add upload preview method};function base64(files){
    	for(var a=0,f=files.length; a<f; A++){// multiple image uploads loop through varread= new FileReader(); ReadAsDataURL (files[a]); // Instantiate object read.readAsDataURL(files[a]); // Read the FileList object read.onload=function(e){return base64 (this.result) preview(base64_arr); }}};returnway; }) ();Copy the code

If you want to create a base64, you need to instantiate the object with FileReader and then read it. If you want to create a Base64, you need to wait until the onload is finished. There may be a difference in loading time due to the size of the image, the small image will be loaded first and the large image will be displayed last, which is not what we need. It could be the other way around!

Have thought about using the count method, this way is often used in node asynchronous, but the count method can only know the end, and can not change the order of upload, with promise can not solve, promise instance method then than asynchronous queue execution, promise.all method is still not found. The solution is to use the closure to cache the order of the for loop, create an array to append the base64 of the images in that order, and finally add them to the page in one go.

functionBase64 (files){var base64_arr =[],// Contains a FileList of each base64 graphfor(var a=0,f=files.length; a<f; A++){// multiple image uploads loop through varread= new FileReader(); ReadAsDataURL (files[a]); // Instantiate object read.readAsDataURL(files[a]); // Read the FileList object. Onload =(function(a){// Closure cache areturn function(e){base64 (this.result) base64_arr[a]={base64:this.result}; // Save base64 for each imageif(base64_arr.length==files.length-1){//
                		preview(base64_arr);
            		}
            	}
            })(a)
    	}
    };
Copy the code

This is a picture upload encountered a pit, there are…. , to be continued…. !