Функция wait с возвратом до завершения $.getJSON

Я пишу функцию, которая должна получить информацию о миниатюре из данного видео с помощью API embed.ly, однако в настоящее время функция возвращает значение, прежде чем оно получит JSON-результат от API.

Я использую следующий код:

function getThumbnail(vUrl) {
    var thumbnail   = '';
    var title       = '';
    var caption     = '';
    var content     = '';

    $.when( $.getJSON("http://api.embed.ly/1/oembed?key=:key&url="+vurl) ).then(function(data){
        var thumbnail = data.thumbnail_url;
            console.log(thumbnail);

        return {
            thumbnail:thumbnail,
            vurl:vurl
        }
    });
}

Однако при использовании консоли Javascript Chrome я вижу, что:

  • функция называется
  • undefined возвращается
  • Запрос XHR завершен.
  • содержимое переменной миниатюр отображается в консоли

Это, очевидно, неправильный порядок.

Любая помощь очень ценится!

Ответы

Ответ 1

Обновленный ответ

getJSON возвращает обещание (только для чтения), поэтому вы можете его прослушать. Но так как вам нужна некоторая пост-обработка, вы бы хотели связать then, который позволяет вам изменять разрешенное значение.

// Now using `then`
function getThumbnail(vUrl){
  return $.getJSON("http://api.embed.ly/1/oembed?key=:key&url="+vurl).then(function(data){
    return {
      thumbnail:data.thumbnail_url,
      vurl:vurl
    }
  });
}

//and in your call will listen for the custom deferred done
getThumbnail('the_vurl_').then(function(returndata){
  //received data!
});

Оригинальный ответ

Вы можете использовать отложенный объект и прослушать done().

function getThumbnail(vUrl) {
    //create our deferred object
    var def = $.Deferred();

    //get our JSON and listen for done
    $.getJSON("http://api.embed.ly/1/oembed?key=:key&url="+vurl)
        .done(function(data){

            //resolve the deferred, passing it our custom data
            def.resolve({
                thumbnail:data.thumbnail_url,
                vurl:vurl
            });
        });

    //return the deferred for listening
    return def;
}

//and in your call will listen for the custom deferred done
getThumbnail('the_vurl_')
    .done(function(returndata){
        //received data!
    });

Вы можете вернуть $.getJSON отложенное, чтобы получить необработанные данные. Но из-за "последующей обработки" в объект требуется отсрочка. Вы также можете передать обратный вызов getThumbnail():

function getThumbnail(vUrl,callback) {
    $.getJSON("http://api.embed.ly/1/oembed?key=:key&url="+vurl,function(returndata){
        callback(returndata);
    });
}

getThumbnail('the_vurl_',function(returndata){
    //received data!
})

Ответ 2

вы можете просто использовать обратный вызов $.getJSON следующим образом:

function result(res) {
  console.log(res);
}

function getThumbnail(vUrl) {
   var thumbnail   = '';
   var title       = '';
   var caption     = '';
   var content     = '';

   $.getJSON("http://api.embed.ly/1/oembed?key=:key&url="+vurl, function(data) {
     var thumbnail = data.thumbnail_url;
     console.log(thumbnail);

     var result = {
        thumbnail:thumbnail,
        vurl:vurl
      };

     // passing the result to a function
     getResult(result);

   });
}

Примечание:

Вы видите, что я вызываю функцию для передачи результата, где вы пытаетесь return, но вы не можете return привести к функции вызывающего абонента. Поскольку $.getJSON является асинхронным.