Как передать результат асинхронной функции в функцию ajax в качестве параметра в js / jquery? - PullRequest
0 голосов
/ 16 февраля 2020

Я пытаюсь сохранить код изображения base64 для снимка видео ...

Для этого у меня есть первая найденная функция, которая создает нужный снимок, эта функция, videoSnap, имеет вид асинхронный, и я хотел бы отправить его через функцию ajax для дальнейших действий.

Проблема в том, что результат моего videoSnap завершается намного позже вызова ajax, таким образом, в любое время я При попытке отправить результат в качестве параметра функции ajax, результат остается неопределенным ...

Как я могу сделать это, чтобы работать? Я думал о функции обещания с then (), но все еще с тем же результатом ... Я продолжаю получать код base64 после вызова ajax, что делает его неэффективным ...

Я начинаю испытывать недостаток в решении и идея ... ^^ '

Большое спасибо заранее за вашу большую помощь! :)

    getTime = function (){
        var t = new Date();
        return t.getTime();
    }

    dump = function (r) {
        var pre = document.createElement('pre');
        pre.innerHTML = r;
        document.body.appendChild(pre)
    }

    videoSnap = function (file){
        var reader = new FileReader();
        if (file.type.match('video')) {
            reader.onload = function() {
              var blob = new Blob([reader.result], {type: file.type});
              var url = URL.createObjectURL(blob);
              var video = document.createElement('video');
              var timeupdate = function() {
                var snap = snapImage();
                if (snap.success) {
                  video.removeEventListener('timeupdate', timeupdate);
                  video.pause();
                  dump(getTime()+' : '+snap.image);
                  return snap.image;
                }else{
                  return false;
                }
              };
              video.addEventListener('loadeddata', function() {
                var snap = snapImage();
                if (snap.success) {
                  video.removeEventListener('timeupdate', timeupdate);
                  dump(getTime()+' : '+snap.image);
                  return snap.image;
                }else{
                  return false;
                }
              });
              var snapImage = function() {
                var canvas = document.createElement('canvas');
                canvas.width = video.videoWidth;
                canvas.height = video.videoHeight;
                canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
                var image = canvas.toDataURL();
                var success = image.length > 100000;
                var result = { success: success, image: image };
                return result;
              };
              video.addEventListener('timeupdate', timeupdate);
              video.preload = 'metadata';
              video.src = url;
              // Load video in Safari / IE11
              video.muted = true;
              video.playsInline = true;
              video.play();
            };
            reader.readAsArrayBuffer(file);
        }else{
            return false;
        }
    }

    dump(getTime());

    var base64Img = videoSnap(videoFile);

    formData.append("videoSnap",base64Img);

    /*
    function videoSnapPromise(vid) {
        return new Promise((resolve) => {
        resolve(videoSnap(vid));
      })
    }   
    function appendResolve(resolve) {
        formData.append("videoSnap",resolve);
    }

    const promise = videoSnap(videoFile);
    promise.then(appendResolve);
    */

    dump(getTime());

    $.ajax({
        type: 'POST',
        url: 'uploadBase64Img.php',
        timeout: 10000,
        data: formData,
        processData: false, 
        contentType: false, 
        dataType: "json",
        complete: function() {
            // complete function
        }
    });

    dump(getTime());

1 Ответ

0 голосов
/ 16 февраля 2020

Один из способов сделать это - создать функцию обратного вызова и отправить ее первой функции в качестве параметра, а затем выполнить рефакторинг вашей первой функции для вызова этого обратного вызова и передачи ему результата операции вместо ее возврата.

примерно так должно работать:

getTime = function() {
  var t = new Date();
  return t.getTime();
}

dump = function(r) {
  var pre = document.createElement('pre');
  pre.innerHTML = r;
  document.body.appendChild(pre)
}


var videoSnap = function(file, callback) {
  var reader = new FileReader();
  if (file.type.match('video')) {
    reader.onload = function() {
      var blob = new Blob([reader.result], {
        type: file.type
      });
      var url = URL.createObjectURL(blob);
      var video = document.createElement('video');
      var timeupdate = function() {
        var snap = snapImage();
        if (snap.success) {
          video.removeEventListener('timeupdate', timeupdate);
          video.pause();
          dump(getTime() + ' : ' + snap.image);
          callback(snap.image);
        } else {
          callback(false);
        }
      };
      video.addEventListener('loadeddata', function() {
        var snap = snapImage();
        if (snap.success) {
          video.removeEventListener('timeupdate', timeupdate);
          dump(getTime() + ' : ' + snap.image);
          callback(snap.image);
        } else {
          callback(false);
        }
      });
      var snapImage = function() {
        var canvas = document.createElement('canvas');
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
        var image = canvas.toDataURL();
        var success = image.length > 100000;
        var result = {
          success: success,
          image: image
        };
        callback(result);
      };
      video.addEventListener('timeupdate', timeupdate);
      video.preload = 'metadata';
      video.src = url;
      // Load video in Safari / IE11
      video.muted = true;
      video.playsInline = true;
      video.play();
    };
    reader.readAsArrayBuffer(file);
  } else {
    callback(false);
  }
}



var doAjax = function(base64Img) {
  var formData = FormData();
  formData.append("videoSnap", base64Img);
  $.ajax({
    type: 'POST',
    url: 'uploadBase64Img.php',
    timeout: 10000,
    data: formData,
    processData: false,
    contentType: false,
    dataType: "json",
    complete: function() {
      // complete function
    }
  });

}


videoSnap(videoFile, doAjax);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...