4

这让我完全困惑。我正在尝试浏览一系列 Youtube id 以检查视频是否仍然存在。

我有一个数组中的所有 id,并想检查 gdata api 以查看是否获得 XML 结果或视频未找到 404 消息。

我在 SO 上找到了一个函数来检查每个 id 并向表中添加一行。

var ytarray = ARRAY OF YOUTUBE IDs
var yttitles = ARRAY OF MATCHING TITLES FOR THE VIDS
var urlExists = function(url, callback){
$.ajax({
            type: 'HEAD',
            url: url,
            success: function() {
                callback(true);
            },
            error: function() {
                callback(false);
            }            
        });

    }
    var length = ytarray.length,
    for (var i = 0; i < length; i++) {
    urlExists('http://gdata.youtube.com/feeds/api/videos/'ytarray[i], function(success) {
        if (success) {
              $('#rows').append('<tr><td>'+yttitles[i]+'</td><td>'+ytarray[i]+'</td><td style="color: green">Found</td></tr>');
        } else {
              $('#rows').append('<tr><td>'+yttitles[i]+'</td><td>'+ytarray[i]+'</td><td style="color: red">Not Found</td></tr>');
        }
    });
    };
});
});

该表已填满,但所有行都包含最后一个视频的信息,而不是每个视频,因为它通过循环。

使用警报进行测试,似乎在所有 for 循环完成之前表格不会被填写。

我想知道这是否与我没有正确处理 AJAX 的异步特性有关?

4

3 回答 3

2
var ytarray   = ["ARRAY OF YOUTUBE IDs"],
    yttitles  = ["ARRAY OF MATCHING TITLES FOR THE VIDS"],
    urlExists = function(url){
        return $.ajax({
            type: 'HEAD',
            url : url
        });
    },
    output = function(state, i) {
        var tr  = $('<tr />'),
            td1 = $('<td />', {text : yttitles[i]}),
            td2 = $('<td />', {text : ytarray[i]}),
            td3 = $('<td />', {text : state ? 'Found' : 'Not found', 
                               style: state ? 'color: green' : 'color:red'});

        $('#rows').append( tr.append(td1, td2, td3) );
    },
    length = ytarray.length;

for (var i = 0; i < length; i++) {
    (function(k) {
        urlExists('http://gdata.youtube.com/feeds/api/videos/' + ytarray[k])
           .done(function() {
             output(true, k);
           }).fail(function() {
                output(false, k);
        });
    })(i);
}

花了一些时间弄清楚,但您需要一些闭包,以及处理异步行为的不同方式。

于 2013-05-04T19:13:45.853 回答
2

我对如何以同步方式执行 URL 验证感到困惑。然后我碰巧遇到了 YQL,玩了一会儿,然后写了这个:

  function isValidURL(url) {
    var encodedURL = encodeURIComponent(url);
    var isValid = false;

    $.ajax({
      url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + encodedURL + "%22&format=json",
      type: "get",
      async: false,
      dataType: "json",
      success: function(data) {
        isValid = data.query.results != null;
      },
      error: function(){
        isValid = false;
      }
    });

    return isValid;
  }

用法很简单:

var isValid = isValidURL("http://www.wix.com");
alert(isValid ? "Valid URL!!!" : "Damn...");

希望这可以帮助任何尝试同步验证 URL 的人。

于 2014-05-07T20:46:22.563 回答
2

尽量保留 i。将在 ajax 响应之后调用回调,直到 for 循环完成,因此 i 的值将等于长度。

   for (var i = 0; i < length; i++) {
          (function(i){
            urlExists('http://gdata.youtube.com/feeds/api/videos/'ytarray[i], function(success) {
                if (success) {
                      $('#rows').append('<tr><td>'+yttitles[i]+'</td><td>'+ytarray[i]+'</td><td style="color: green">Found</td></tr>');
                } else {
                      $('#rows').append('<tr><td>'+yttitles[i]+'</td><td>'+ytarray[i]+'</td><td style="color: red">Not Found</td></tr>');
                }
            });
        })(i)
     }
于 2013-05-04T19:06:10.647 回答