亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

javascript - js最好怎麼在兩個AJax非同步操作之後執(zhí)行一個新的操作
世界只因有你
世界只因有你 2017-07-05 10:54:02
0
11
1836

今天碰到一個面試問題,就是如果頁面中有兩個非同步ajax的操作,因為不確定這兩個非同步操作的執(zhí)行順序,怎麼在這兩個操作都執(zhí)行完再執(zhí)行一個新的操作,最好的方法是什麼?

我當時回答了方法一:巢狀兩個ajax,在第二個ajax的回傳函數(shù)中執(zhí)行新的操作。面試官回覆:這種方法太矬了。

於是想了下回答方法二:透過定時器setTimeout監(jiān)聽局部變量,確保兩個非同步操作執(zhí)行完了再執(zhí)行新操作。面試官回覆:這種方式表現(xiàn)不好,能不能想到一個簡單又更合理的方法。

當時思考未果
所以把這個問題放上來尋求最好的方法是什麼?歡迎討論指點

世界只因有你
世界只因有你

全部回覆(11)
學習ing

1.Promise 包裝非同步ajax操作,
2.定義async 函數(shù),
3.用await等待promise資料非同步取得完成
這一種方法簡潔高效,下面請看我專門給你寫的範例程式碼
我懶得用ajax取得資料了,就用settimeout這個函數(shù)模擬取得資料吧,這個函數(shù)是異步的,原理效果一樣。

//模擬ajax異步操作1
function ajax1() {
    const p = new Promise((resolve, reject) => {
        setTimeout(function() {
            resolve('ajax 1 has be loaded!')
        }, 1000)
    })
    return p

}
//模擬ajax異步操作2
function ajax2() {
    const p = new Promise((resolve, reject) => {
        setTimeout(function() {
            resolve('ajax 2 has be loaded!')
        }, 2000)
    })
    return p
}
//等待兩個ajax異步操作執(zhí)行完了后執(zhí)行的方法
const myFunction = async function() {
    const x = await ajax1()
    const y = await ajax2()
        //等待兩個異步ajax請求同時執(zhí)行完畢后打印出數(shù)據(jù)
    console.log(x, y)
}
myFunction()
漂亮男人

http://api.jquery.com/jQuery....

為情所困

目前瀏覽器環(huán)境中開箱即用的原生方法是 Promise.all。

以呼叫我的地圖庫 Sinomap Demo 為例,這個頁面中為了載入一張地圖,需要多個同時發(fā)起但不能確保返回順序的請求:

  1. 中國地形資料

  2. 各省份數(shù)值 JSON 資料

  3. 多種圖表疊加時多種圖表存在多種 JSON 資料需透過不同資料介面回傳…

解決方法直接在未包裝的 http://sinomap.ewind.us/demo/demo.js 中,範例:

// 封裝地形 GeoJSON 數(shù)據(jù)接口
// 將每個數(shù)據(jù)接口封裝為一個返回 Promise 的函數(shù)
function getArea () {
  return new Promise((resolve, reject) => {
    fetch('./resources/china.json').then(resp =>
      resp.json().then(china => resolve(china))
    )
  })
}

// 封裝分色地圖數(shù)據(jù)接口
function getPopulation () {
  return new Promise((resolve, reject) => {
    fetch('./resources/china-population.json').then(resp =>
      resp.json().then(data => resolve(data))
    )
  })
}

// 封裝城市數(shù)據(jù)接口
function getCity () {
  return new Promise((resolve, reject) => {
    fetch('./resources/city.json').then(resp =>
      resp.json().then(data => resolve(data))
    )
  })
}

// 使用 Promise.all 以在三個數(shù)據(jù)接口均異步成功后,執(zhí)行回調(diào)邏輯
Promise.all([getArea(), getPopulation(), getCity()]).then(values => {
  // 依次從返回的數(shù)據(jù)接口數(shù)組中獲取不同接口數(shù)據(jù)
  let china = values[0]
  let population = values[1]
  let city = values[2]
  // 使用數(shù)據(jù)
  doWithData(china, population, city)
})

這樣透過 Promise 不僅實現(xiàn)了回呼邏輯的解耦,也實現(xiàn)了基礎(chǔ)的非同步流程控制。

小葫蘆

剛剛看到j(luò)query 的when 方法,所以給你重寫了一個,不一定有jquery的那麼好,但至少能實現(xiàn)效果了,可以在控制臺直接輸入下述代碼試試,我勒個去,寫了我整整半小時。 。

function ajax(callback){
    callback = callback || function(){};
    var xhr = new XMLHttpRequest();
    xhr.open("get","");
    xhr.onload = function(res){ callback(res) };
    xhr.send(null); 
}

var when = (function(){
    var i = 0,
        len = 0,
        data = [];
    return function(array,callback){
        callback = callback || function(){};
       len = len || array.length;
        var fn = array.shift();
       
       fn(function(res){
            i++;
            data.push(res);
            if(i < len){
                when(array,callback);
            } else {
                callback(data);
            } 
       });   
    };
})();

when([ajax,ajax],function(data){
    console.log(data);
});
給我你的懷抱

問下能不能用jQ,能用的話直接:

$.when($.ajax("page1"), $.ajax("page2")).done(function(){});

順帶給個$.when的文檔參考

為情所困

我覺得是Promise的方法 all還是什麼的

學習ing

你的問題是有三件事 a,b,c。 c要在a和b結(jié)束之後再執(zhí)行。

有很多方法: 例如你說的嵌套法 還有暴力監(jiān)聽法

這個問題我曾經(jīng)考慮過,以下是我的解答。

異步發(fā)射器

用數(shù)組保存如何執(zhí)行非同步操作

注意裡面的函數(shù)都有個參數(shù) commit ,它是一個函數(shù) 用來來回傳值。 當ajax成功的時候 把回傳值回傳進去就好

// 兩個異步操作  
var todos = [
    function getUser(commit){ 
        setTimeout(() => {
            commit({  // 這里是異步結(jié)束的時候 利用 commit 把值回傳 
                name: 'eczn',
                age: 20
            }, 233); 
        }); 
    },
    function getLoc(commit){
        setTimeout(() => {
            commit({
                area: '某個地方'
            });
        }, 333); 
    }
]; 

編寫發(fā)射器

processors 是 todos 這樣的數(shù)據(jù)。 cb 是最終回調(diào)。

function launcher(processors, cb){
    var o = {}; 
    var count = 0; 
    if (processors.length === 0) cb(o); 

    processors.forEach((func, idx) => {
        func(function commit(asyncVal){ // 這就是commit函數(shù) 
            // 把 asyncVal 的所有屬性合并到 o 上 
            // ( 利用 Object.keys 獲取對象全部屬性名 )
            Object.keys(asyncVal).forEach(key => {
                o[key] = asyncVal[key]; 
            }); 
            
            // 計數(shù)器自加 
            count++; 
            // 如果發(fā)射器全部發(fā)射完畢則調(diào)用回調(diào)函數(shù) cb 并把 o 作為參數(shù)傳遞
            if (count === processors.length) cb(o); 
        }); 
    }); 
}

並發(fā)他們

執(zhí)行非同步發(fā)射器 並提供 最終回調(diào)

launcher(todos, function(whereEczn){
    // todos 里面存放的異步操作的值由 commit 回調(diào)返回
    // 全部回調(diào)跑完的時候 就會執(zhí)行當前這段函數(shù) 并把期望值返回
    console.log(whereEczn); 

    // 按順序輸出
    ['name', 'area'].forEach(key => {
        console.log(`${key}: ${whereEczn[key]}`); 
    }); 
});

Link

https://eczn.coding.me/blog/%...

世界只因有你

可以定義個變數(shù)a=0,ajax請求成功後在回呼裡設(shè)定a++;
然後在兩個回調(diào)中均判斷下a==2 執(zhí)行操作函數(shù)

Peter_Zhu

設(shè)定兩個flag,然後兩個ajax呼叫同一個回調(diào),在這個回呼中判斷兩個flag都為true才執(zhí)行後續(xù)操作。

漂亮男人

把ajax寫在另一個ajax裡面再在回調(diào)那裡執(zhí)行

最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板