24336


JavaScriptで指定した画像URLに画像が存在するかを判定することは可能でしょうか。

やりたいことは「画像1」と「画像2」のURLが分かっている場合に、

[code]

    function getImageURL() {
        /* 「画像1のURL」に画像が存在すれば「画像1のURL」を返却する */
        /* 「画像2のURL」に画像が存在すれば「画像2のURL」を返却する */
        /* 両方なければ''を返却する */
    }
    
[/code]

と言うことがやりたいです。  
色々調べてはみたのですが、  
JavaScriptでは画像の読み込み処理を非同期で行っているようで、  
読み込んでいる間に、次の処理に行ってしまい、''が返却されてしまいます。  
また↓のサイトを参考にpromiseを使用してやってみたのですが、  
全部の処理が終わった後に、onFulfilledが呼ばれるので想定した動作になりませんでした。

JavaScript プログラミング講座  
<http://hakuhin.jp/js/promise.html>

[code]

    var url = window.location.origin;
    var url1 = url + 'image/1.jpg';
    var url2 = url + 'image/2.jpg';
    
    function imageElementCreateAndLoad (url) {
        var promise = new Promise(function(resolve, reject) {
            var image = new Image();
            image.onload = function () {
                resolve(image);
            };
            image.onerror = function() {
                reject(new Error("Not Found"));
            };
            image.src = url;
        });
        return promise;
    }
    
    var promise = imageElementCreateAndLoad(url1);
    promise.then(
        function onFulfilled(value) {
            _tracking['imageUrl'] = value.src;
        }
    );
    promise = imageElementCreateAndLoad(url2);
    promise.then(
        function onFulfilled(value) {
            _tracking['imageUrl'] = value.src;
        }
    );
    
[/code]

上記で記述した、getImageURLが上手く動くようにすることはJavaScriptでは可能でしょうか。  
ご存知の方がいらっしゃいましたら、教えてください。  
よろしくお願いします。


CC BY-SA 3.0
2016-04-25T10:36:45.617
24332
2016-04-25T20:14:30.517
7918
question
javascript
JavaScriptで任意URLに画像が存在しているかを判定したい。


XMLHttpRequest で GET か HEAD で画像のURLにリクエストを投げると status が 200 か 404 かで判断出来そうです。

[code]

    var url = window.location.origin;
    var url1 = url + "/image/1.png";
    var url2 = url + "/image/2.png";
    
    function load(_url){
      var xhr;
      xhr = new XMLHttpRequest();
      xhr.open("HEAD", _url, false);  //同期モード
      xhr.send(null);
      return xhr.status;
    }
    
    function getImageUrl(){
      if(load(url1) == 200)
        return url1;
      if(load(url2) == 200)
        return url2;
      return "null";
    }
    
[/code]


CC BY-SA 3.0
2016-04-25T13:08:47.337
24336
2016-04-25T13:08:47.337
5008
24332
answer


１つ目の`promise`の結果を待つ必要があります。

[code]

    var url = window.location.origin;
    var urls = [
      url + 'image/1.jpg',
      url + 'image/2.jpg'
    ];
    
    function imageElementCreateAndLoad (url) {
        var promise = new Promise(function(resolve, reject) {
            var image = new Image();
            image.onload = function () {
                resolve(image);
            };
            image.onerror = function() {
                reject(new Error("Not Found"));
            };
            image.src = url;
        });
        return promise;
    }
    
    urls.reduce(
        function (promise, url) {
            return promise.then(
                function onFulfilled(image) {
                    return image.src;
                },
                function onRejected(value) {
                    return imageElementCreateAndLoad(url)
                }
            )
        },
        Promise.reject()
    )
    .then(
        function onFulfilled(url) {
            return url;
        },
        function onRejected(value) {
            return ''
        }
    )
    .then(
        function onFulfilled(url) {
            console.log(JSON.stringify(url));
        }
    )
    
[/code]

>
> 参考：[Promiseと組み合わせて非同期の直列処理を使う](http://qiita.com/59naga/items/7644d019b8050a201547#promise%E3%81%A8%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%E3%81%A6%E9%9D%9E%E5%90%8C%E6%9C%9F%E3%81%AE%E7%9B%B4%E5%88%97%E5%87%A6%E7%90%86%E3%82%92%E4%BD%BF%E3%81%86)


CC BY-SA 3.0
2016-04-25T20:14:30.517
24343
2016-04-25T20:14:30.517
9834
24332
answer