js處理併發請求
阿新 • • 發佈:2018-11-12
1,Promise並行執行非同步任務。
試想一個頁面聊天系統,我們需要從兩個不同的URL分別獲得使用者的個人資訊和好友列表,這兩個任務是可以並行執行的,用Promise.all()
實現如下:
var p1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, 'P1'); }); var p2 = new Promise(function (resolve, reject) { setTimeout(resolve, 600, 'P2'); }); // 同時執行p1和p2,並在它們都完成後執行then: Promise.all([p1, p2]).then(function (results) { console.log(results); // 獲得一個Array: ['P1', 'P2'] });
有些時候,多個非同步任務是為了容錯。比如,同時向兩個URL讀取使用者的個人資訊,只需要獲得先返回的結果即可。這種情況下,用Promise.race()
實現:
var p1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, 'P1'); }); var p2 = new Promise(function (resolve, reject) { setTimeout(resolve, 600, 'P2'); }); Promise.race([p1, p2]).then(function (result) { console.log(result); // 'P1' });
由於p1
執行較快,Promise的then()
將獲得結果'P1'
。p2
仍在繼續執行,但執行結果將被丟棄。
如果我們組合使用Promise,就可以把很多非同步任務以並行和序列的方式組合起來執行。
/* 先定義一個返回Promise物件的Ajax過程 */ var getAjaxPromise = function(option){ return new Promise(function(resolve, reject){ $.ajax({ url: option.url, type: 'get', data: option.data || '', success: function(data){ resolve(data); }, error: function(error){ reject(error); } }); }); }; /* 啟動第1個非同步任務 */ var p1 = getAjaxPromise({ url: 'root/url/1' }); p1.then(function(data1){ /* 處理第1個非同步任務的結果 */ console.log(data1); /* 然後啟動第2個非同步任務 */ return getAjaxPromise({ url: 'root/url/2' }); }) .then(function(data2){ /* 處理第2個非同步任務的結果 */ console.log(data2); });
ajax改為同步
如在jquery中將async引數設定為false
$.ajax({
url:"/jquery/test1.txt",
async:false
});
設定結束標識
簡單一點的可以設定計數器,每完成一個非同步函式加1,或者設定一個數組,每執行完一個非同步函式更新陣列。
回撥計數
var cnt = 0;
function async1(){
//do sth...
callback();
}
function async2(){
//do sth...
callback();
}
function callback(){
cnt++;
if(2==cnt) console.log('都已執行完畢');
}
迴圈阻塞
var cnt = 0;
function async1(){
//do sth...
cnt++;
}
function async2(){
//do sth...
cnt++;
}
while(2>cnt){}
迴圈非阻塞
不建議過多使用,以免影響效能
var cnt = 0;
function async1(){
//do sth...
cnt++;
}
function async2(){
//do sth...
cnt++;
}
var interval = setInterval(function(){
if(2===cnt){
console.log('已執行完成');
clearInterval(interval)
}
}
第三方框架實現
jquery
目前我在專案中採用的方式
var d1 = $.Deferred();
var d2 = $.Deferred();
function async1(){
d1.resolve( "Fish" );
}
function async2(){
d2.resolve( "Pizza" );
}
$.when( d1, d2 ).done(function ( v1, v2 ) {
console.log( v1 + v2 + '已完成');
});