異步與它無關。一旦進入成功回調,異步部分已經完成。問題在於,在第一次更改有時間加載之前,您要再次更改窗口位置。換句話說,這與異步問題完全相反;問題是這段代碼是同步的,運行速度太快。
但是,這裏的方法是有缺陷的。它可能工作,如果瀏覽器被迫下載文件,因爲那麼第一次更改爲window.location
本身不會導致瀏覽器視圖更改。由於PDF通常是瀏覽器可瀏覽的類型,但這並不能保證。無論如何,你仍然有同樣的問題需要延遲第二個電話,直到第一個電話得到響應,這基本上是不可能的。這種類型的事情沒有內置的事件,所以最好你可以做的就是使用setTimeout
延遲1-2秒,只是希望這是足夠的時間來獲得第一個響應。即使這樣,如果它花費更長時間,您的代碼也會再次中斷。換句話說,它會變得非常脆弱。
簡單的事實是,這僅僅不是HTTP的工作方式。你基本上試圖爲單個請求返回兩個響應,這是不可能的。這是一種巧妙的方式,可以避開協議中固有的限制,我會給你的,但最終還是不夠。
所有這一切說,你可以實際上使通過HTML5文件API和AJAX這種情況發生,但你的解決方案,然後將只與現代瀏覽器兼容(基本上一切,除了IE 10和下)。如果你不需要支持較低版本的IE,那麼你可以使用下面的代碼來代替:
function (response) // success callback
{
$http.get('@Url.Action("PdfCreator", "someController")?Id=' + $scope.id').then(
function (response) // success callback
{
var a = document.createElement('a');
var url = window.URL.createObjectURL(response.data);
a.href = url;
a.download = 'myfile.pdf';
a.click();
window.URL.revokeObjectURL(url);
window.location = '@Url.Action("Index","AnotherController")';
},
function (response) // failure callback
{
alert(response.statusText);
}
);
},
的祕訣是在獲取通過AJAX的PDF,然後創建一個對象URL出來的PDF數據。然後,您可以使用它在DOM中創建一個錨點元素並動態「點擊」它以提示下載。但是,需要注意的是,我還沒有嘗試過使用Angular,所以我不確定$http
是否支持獲取二進制響應。我知道jQuery,你只需告訴它,XHR對象的響應類型是'blob',但我不確定你是否可以或如何使用Angular做同樣的事情。作爲替代,您可以直接使用XMLHttpRequest
直接用於此特定AJAX,並且只需設置xhr.responseType = 'blob'
即可。