2021年7月25日 星期日

jQuery同步Ajax阻塞問題及解決辦法

 由於開發JavaScript是單線程的,當我們使用Ajax同步請求時,線程將停在等待請求response的地方,直到收到response,線程才繼續執行。

這導致了程序無法執行其他js命令, 帶來了線程阻塞問題,具體體現方式是UI界面卡住。  這裏的ajax不能用異步的,否則函數返回時,result還未賦值,會出錯。所以加了async:false。但是帶來的另一個問題就是線程阻塞。如下:

function getData(){ var result; $.ajax({ url : 'p.php', async : false, success: function(data){ result = data; } }); return result; }

找了一下資料,發現幾種方法都可以完美解決問題,具體代碼如下:

Deferred:

function getData(){ var defer = $.Deferred(); $.ajax({ url : 'p.php', //async : false, success: function(data){ defer.resolve(data) } }); return defer.promise(); } // getData()返回Promise對象 $.when(getData()).done(function(data){ alert(data); });

Promise:

getData() { return new Promise((resolve, reject) => { $.ajax({ url : 'p.php', //async : false, success: function(data){ defer.resolve(data) }, error: function(result) { reject("throw error") } }) }) } // 調用 getData().then(function(data){ console.log(data) }).catch(function(err){ console.log(err) })

在ES6中,還可以使用Generator來創建異步編程

function* getData() { let result; $.ajax({ url : 'p.php', success: function(data){ result = data; } }); yield; return result } var gd = getData() console.log(gd.next()) // {value: undefined, done: false} console.log(gd.next()) // {value: data, done: false}

沒有留言:

張貼留言