Search code examples
javascriptjqueryasync-awaitsynchronization

How to get synchronous load using async and await in jquery on loadedmetadata?


I want to use jquery to get audio duration in synchronous by await. I want to get the alert messages in this order :

   111 
   222 leng=1.549188
   333 duration=1.549188 
   444 

But I get the asynchronous order :

   111 
   333 duration=9999 
   444 
   222 leng=1.549188 

How to fix it ?

var duration = 99999 ; 

async function getAudioUrlDuration(src, callBackFun) {
    var audio = new Audio();
    audio.src = src;
    await $(audio).on("loadedmetadata", function(){
        callBackFun( audio.duration );
        duration = audio.duration ;
    });
}
function callBackFun3(leng){ 
    alert('222 leng='+leng) ; 
}
var src = "https://www.w3schools.com/tags/horse.mp3" ;

async function aaa(){
  alert(111);
  await getAudioUrlDuration(src, callBackFun3 )  ; 
  alert( '333  duration='+duration ) ; 
  alert(444);
} 
 
 aaa();

Solution

  • The issue is the on function of jQuery doesn't return a promise to await for, you need to turn the getAudioUrlDuration function to return a promise which will be resolved on the on callback success.

    var duration = 99999; 
    async function getAudioUrlDuration(src) {
        var audio = new Audio();
        audio.src = src;
        // Return a promise that resolves when the loadedmetadata event is triggered
        return new Promise((resolve) => {
            $(audio).on("loadedmetadata", function(){
                duration = audio.duration;
                resolve(audio.duration);
            });
                
            $(audio).on("error", function() {
                reject(new Error("Failed to load audio metadata")); // Reject the promise with an error
            });
        });
    }
    
    function callBackFun3(leng){ 
        alert('222 leng=' + leng); 
    }
    
    var src = "https://www.w3schools.com/tags/horse.mp3";
    
    async function aaa(){
        try {
          alert(111);
          var audioDuration = await getAudioUrlDuration(src);
          callBackFun3(audioDuration);  
          alert('333 duration=' + duration); 
          alert(444);
        } catch (e) {
          console.log(e)
        }
        
    }
    
    aaa();