Recursive Promise in javascript

前端 未结 6 1670
没有蜡笔的小新
没有蜡笔的小新 2020-12-08 01:58

I\'m writing a Javascript Promise that finds the final redirect URL of a link.

What I\'m doing is making a HEAD request in a Promise<

6条回答
  •  一个人的身影
    2020-12-08 02:39

    The problem is that the promise you return from getRedirectUrl() needs to include the entire chain of logic to get to the URL. You're just returning a promise for the very first request. The .then() you're using in the midst of your function isn't doing anything.

    To fix this:

    Create a promise that resolves to redirectUrl for a redirect, or null otherwise:

    function getRedirectsTo(xhr) {
        if (xhr.status < 400 && xhr.status >= 300) {
            return xhr.getResponseHeader("Location");
        }
        if (xhr.responseURL && xhr.responseURL != url) {
            return xhr.responseURL;
        }
    
        return null;
    }
    
    var p = new Promise(function (resolve) {
        var xhr = new XMLHttpRequest();
    
        xhr.onload = function () {
            resolve(getRedirectsTo(xhr));
        };
    
        xhr.open('HEAD', url, true);
        xhr.send();
    });
    

    Use .then() on that to return the recursive call, or not, as needed:

    return p.then(function (redirectsTo) {
        return redirectsTo
            ? getRedirectUrl(redirectsTo, redirectCount+ 1)
            : url;
    });
    

    Full solution:

    function getRedirectsTo(xhr) {
        if (xhr.status < 400 && xhr.status >= 300) {
            return xhr.getResponseHeader("Location");
        }
        if (xhr.responseURL && xhr.responseURL != url) {
            return xhr.responseURL;
        }
    
        return null;
    }
    
    function getRedirectUrl(url, redirectCount) {
        redirectCount = redirectCount || 0;
    
        if (redirectCount > 10) {
            throw new Error("Redirected too many times.");
        }
    
        return new Promise(function (resolve) {
            var xhr = new XMLHttpRequest();
    
            xhr.onload = function () {
                resolve(getRedirectsTo(xhr));
            };
    
            xhr.open('HEAD', url, true);
            xhr.send();
        })
        .then(function (redirectsTo) {
            return redirectsTo
                ? getRedirectUrl(redirectsTo, redirectCount + 1)
                : url;
        });
    }
    

提交回复
热议问题