jQuery обещают каждый цикл

Я создаю UserScript, который будет генерировать список URL-адресов для фотогалереи пользователей. Пользовательская галерея может иметь несколько страниц, каждая страница имеет несколько эскизов, которые имеют ссылку на страницу, содержащую url-адрес полноразмерного изображения.

Я использую jQuery для запроса страниц, хотя я не получаю желаемых результатов, когда пользовательская галерея содержит только 1 страницу. Я получаю некоторые результаты, когда пользовательская галерея содержит несколько страниц, но я получаю только 1 страницу результатов.

var userID = 0;

function getUserID() {
    var query = window.location.search;
    var regex = /UserID=(d+)/;
    var regexResult = query.match(regex);
    if (regexResult !== null) {
        return regexResult[0].replace('UserID=', '');
    } else {
        return 0;
    }
}

function getGallery(userID) {
    function getGalleryPage(userID, page, gallery) {
        var data = {};
        if(page > 0) {
            data = { btnNext: ">", PageNo: page };
        }

        var url = 'http://www.domain.com/' + userID;

        return $.ajax({
            method: 'POST',
            url: url,
            data: data,
            dataType: 'html'
        }).then(function(result){
            $result = $(result);
            $result.find('form[name="frmGallery"]').find('img').each(function() {
                var url = ''
                // Do stuff to get url

                getGalleryImage(url).done(function(imageLink) {
                    gallery.push(imageLink);
                });
            });

            $btnNext = $result.find('input[name="btnNext"]');
            if($btnNext.length > 0) {
                page += 1;
                return getGalleryPage(userID, page, gallery);
            } else {
                return(gallery);
            }
        });
    }
    return getGalleryPage(userID, 0, []);
}

function getGalleryImage(url) {
    return $.ajax({
        method: 'GET',
        url: url,
        dataType: 'html'
    }).then(function(result){
        var imageUrl = '';
        // Do stuff to get full sized image url
        return imageUrl;
    });
}

jQuery(document).ready(function($) {
    userID = getUserID();
    if(userID === 0)
        return;

    getGallery(userID).done(function(gallery) {
        $.each(gallery, function(index, value) {
            console.log(value);
        });
    });
});

Я думаю, что эта часть моего сценария не является правильной:

$result.find('form[name="frmGallery"]').find('img').each(function() {
                var url = ''
                // Do stuff to get url

                getGalleryImage(url).done(function(imageLink) {
                    gallery.push(imageLink);
                });
            });

1 ответ

  1. Как написано, нет никакой попытки собрать внутренние обещания, возвращенные getGalleryImage().

    Необходимо сопоставить поставляемые элементы img с массивом обещаний и агрегировать ихjQuery.when().

    Я бы написал что-то вроде этого :

    jQuery(function($) {
        var userID;
    
        function getUserID() {
            var query = window.location.search;
            var regex = /UserID=(\d+)/;
            var regexResult = query.match(regex);
            if (regexResult !== null) {
                return regexResult[0].replace('UserID=', '');
            } else {
                return 0;
            }
        }
    
        function getGallery(userID) {
            var gallery = [];
            var page = 0;
            var url = 'http://www.domain.com/' + userID;
            function getGalleryPage() {
                var data = (page > 0) ? { btnNext: ">", PageNo: page } : {};
                return $.ajax({
                    method: 'POST',
                    url: url,
                    data: data,
                    dataType: 'html'
                }).then(function(result) {
                    $result = $(result);
    
                    //map jQuery collection of img elements to Array of promises
                    var promises = $result.find('form[name="frmGallery"]').find('img').map(function(imgElement, i) {
                        var url = ''
                        // Do stuff to get url
                        return getGalleryImage(url);
                    }).get();// .get() is necessary to unwrap jQuery and return Array
    
                    //aggregate promises
                    return $.when.apply(null, promises).then(function() {
                        //accumulate results
                        gallery = gallery.concat(Array.prototype.slice.call(arguments));
                        // recurse/terminate
                        if($result.find('input[name="btnNext"]').length > 0) {
                            page += 1;
                            return getGalleryPage();
                        } else {
                            return gallery;
                        }
                    });
                });
            }
            return getGalleryPage();
        }
    
        function getGalleryImage(url) {
            return $.ajax({
                method: 'GET',
                url: url,
                dataType: 'html'
            }).then(function(result) {
                var imageUrl = '';
                // Do stuff to get full sized image url
                return imageUrl;
            });
        }
    
        userID = getUserID();
        if(userID !== 0) {
            getGallery(userID).then(function(gallery) {
                $.each(gallery, function(index, value) {
                    console.log(value);
                });
            });
        }
    });
    

    Вы также должны установить ограничение на количество рекурсий, на тот случай, если однажды какой-то userID выдаст тысячи страниц.