2017-01-17 20 views
2

ウェブ上のあらゆる場所でこれを見ましたが、この問題を回避するためにコードを修正できませんでした。単にボタンをクリックしたときにトリガーするajax関数があります。 、asyncのChromeとSafari ajaxの問題

$(document).on('click', '.ad-single', function() { 
    var addataObj = doAjax('post_requests', 'get-ad-info', {"id": $(this).data('ad')}, '158', false); // false means DON'T hide the indicator 
    if (addataObj) { 
    loadContent(addataObj.ad); 
    } 
}); 

OK:私は時々、インジケータ(ロードアニメーション)が表示しないようにしたいので、私は私の機能の構築:

function doAjax(action, todo, items, error_num, hide_indicator) { 
    items.action = action; 
    items.do = todo; 
    var postedObj; 

    $.ajax({ 
    type: 'post', 
    dataType: 'html', 
    url: ajaxURL, 
    data: items, 
    async: false, 
    beforeSend: function() { 
     if (!hide_indicator) showIndicator(); 
    }, 
    success: function(data) { 
     if (data) { 
     ajaxObj = JSON.parse(data); 
     if (ajaxObj.ok) { 
      postedObj = ajaxObj; 
     } else { 
      alert(ajaxObj.error); 
      postedObj = false; 
     } 
     } else { 
     alert('[' + error_num + '] Something went wrong.'); 
     postedObj = false; 
     } 
     if (!hide_indicator) hideIndicator(); 
    }, 
    error: function() { 
     alert('[' + error_num + '] Something went wrong.'); 
     postedObj = false; 
     if (!hide_indicator) hideIndicator(); 
    } 

    }); 
    return postedObj; 
} 

そして、ここで私は、関数を呼び出すために私のボタンの上に何をすべきかですが今のところ、Firefoxですべてが正常に機能します。私のボタンをクリックすると、インジケータが表示され、データがajaxによって返されるまで待ってから、再度インジケータを非表示にします。

これはChromeとSafariでは機能しません。この関数は正常に動作し、期待どおりのデータを返しますが、hideIndicator()関数がすぐに呼び出されたようで、これを修正する方法がわかりませんでした。

のFirefox:

enter image description here

ChromeとSafariの:

enter image description here

+0

schronous呼び出しでブロックがロックされるため、ページに更新時間がありません。私はこの同じ質問と重複がたくさんあると確信しています。 – epascarello

+0

私はそれを知っていますが、私の 'loadContent'関数に空を返すので、私はそれを取り除くことができません! – tinyCoder

+0

これは、非同期呼び出しのためにコードが非同期要求を処理するようにする理由です。 – epascarello

答えて

3

async: falseを使用すると、悪です。インターネットはそのような投稿でいっぱいで、ChromeやSafariを含む多くのブラウザが、同期AJAXリクエストの作成に関する多数の警告を表示します。

幸いにも、jQueryの約束はあなたの問題を克服するために使用できます。それはあなたの関数がどのように動作するかを変えず、非同期要求をするために約束の力を活用します。

次のように既存の関数を変更して、結果ではなくAJAXの約束を返すことができます。ここ

function doAjax(action, todo, items, error_num, hide_indicator) { 
    items.action = action; 
    items.do = todo; 

    return $.ajax({ 
     type: 'post', 
     dataType: 'html', 
     url: ajaxURL, 
     data: items, 
     beforeSend: function() { 
     if (!hide_indicator) showIndicator(); 
     } 
    }) 
    .then(function(data) { 
     if (!hide_indicator) { 
     hideIndicator(); 
     } 

     if (data) { 
     ajaxObj = JSON.parse(data); 

     if (ajaxObj.ok) { 
      return ajaxObj; 
     } 

     alert(ajaxObj.error); 
     return false; 
     } 

     alert('[' + error_num + '] Something went wrong.'); 
     return false; 
    }, function() { 
     if (!hide_indicator) { 
     hideIndicator(); 
     } 

     alert('[' + error_num + '] Something went wrong.'); 
     return false; 
    }); 
} 

.then関数は、応答を事前処理するために使用される、およびその後の約束ハンドラに適切な値を返すことができます。

次の約束事ハンドラは、doAjax関数を呼び出し、前処理で返された値に反応して次のように実装できます。

ここ
$(document).on('click', '.ad-single', function() { 
    doAjax('post_requests', 'get-ad-info', {"id": $(this).data('ad')}, '158', false) 
    .then(function(addataObj) { 
     if (addataObj) { 
     loadContent(addataObj.ad); 
     } 
    }); 
}); 

、前.then()とアップ.then()鎖、および値に反応するが(addataObjで受信されている)を返します。 AJAX呼び出しが成功した場合にのみ反応することに注意してください。エラー応答も処理したい場合は、.then()ハンドラへの関数として2番目の引数を渡す必要があります。

これがあなたの問題を解決することを願っています。

+0

それは大変ありがとうございます。私はより多くのことをお願いできますか?純粋なJavaScriptで作成できますか?私はカスタムDOMでフレームワークを使用しています。私は '.then'約束をするためにjQueryファイル全体を含めたくありません。 – tinyCoder

+0

私はそれをした、ありがとう:) – tinyCoder

+0

はいこれは邪悪な真の非同期の真は悪のhahahaです – zero8

関連する問題