js best how to perform a new operation after two AJax async operations
世界只因有你
世界只因有你 2017-07-05 10:54:02
0
11
1697

I encountered an interview question today, that is, if there are two asynchronous ajax operations on the page, because the execution order of the two asynchronous operations is not sure, how to execute a new operation after both operations are executed? What's the best approach?

I answered method one at that time: nest two ajaxes and perform new operations in the return function of the second ajax. Interviewer's reply: This method is too lame.

So I thought about the second answer: monitor local variables through the timer setTimeout, and ensure that the two asynchronous operations are completed before performing a new operation. Interviewer's reply: The performance of this method is not good. Can you think of a simple and more reasonable method?

Thoughts failed at the time
So I put this question up to find what is the best way? Welcome to discuss and give advice

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

reply all(11)
学习ing

1. Promise wraps asynchronous ajax operations,
2. Define async function,
3. Use await to wait for the asynchronous acquisition of promise data to be completed. This method is simple and efficient. Please see the sample code I wrote specifically for you below. I am too lazy to use it. After ajax obtains data, use the settimeout function to simulate obtaining data. This function is asynchronous and has the same principle and effect.

//模拟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异步操作执行完了后执行的方法
const myFunction = async function() {
    const x = await ajax1()
    const y = await ajax2()
        //等待两个异步ajax请求同时执行完毕后打印出数据
    console.log(x, y)
}
myFunction()
漂亮男人

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

为情所困

The current out-of-the-box native method in the browser environment is Promise.all.

Take calling my map library Sinomap Demo as an example. In order to load a map on this page, multiple requests are required to be initiated at the same time but the return order cannot be guaranteed:

  1. China terrain data

  2. JSON data of each province

  3. When multiple charts are overlaid, there are multiple JSON data in multiple charts that need to be returned through different data interfaces...

The solution is directly in the unpackaged http://sinomap.ewind.us/demo/demo.js, example:

// 封装地形 GeoJSON 数据接口
// 将每个数据接口封装为一个返回 Promise 的函数
function getArea () {
  return new Promise((resolve, reject) => {
    fetch('./resources/china.json').then(resp =>
      resp.json().then(china => resolve(china))
    )
  })
}

// 封装分色地图数据接口
function getPopulation () {
  return new Promise((resolve, reject) => {
    fetch('./resources/china-population.json').then(resp =>
      resp.json().then(data => resolve(data))
    )
  })
}

// 封装城市数据接口
function getCity () {
  return new Promise((resolve, reject) => {
    fetch('./resources/city.json').then(resp =>
      resp.json().then(data => resolve(data))
    )
  })
}

// 使用 Promise.all 以在三个数据接口均异步成功后,执行回调逻辑
Promise.all([getArea(), getPopulation(), getCity()]).then(values => {
  // 依次从返回的数据接口数组中获取不同接口数据
  let china = values[0]
  let population = values[1]
  let city = values[2]
  // 使用数据
  doWithData(china, population, city)
})

In this way, Promise not only realizes the decoupling of callback logic, but also realizes basic asynchronous process control.

小葫芦

I just saw the when method of jquery, so I rewrote one for you. It may not be as good as jquery, but at least it can achieve the effect. You can directly enter the following code in the console to try. Let me go and write It took me half an hour. .

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);
});
给我你的怀抱

Ask if I can use jQ. If so, just say:

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

By the way, here is a document reference for $.when

为情所困

I think it’s Promise’s method all or something

学习ing

Your question is there are three things a, b, c. c should be executed after a and b are completed.

There are many methods: such as the nesting method you mentioned, and the violent monitoring method

I have thought about this question before, and here is my answer.

Asynchronous emitter

How to perform asynchronous operations using array storage

Note that the functions inside all have a parameter commit , which is a function used to return a value. When ajax succeeds, just pass the return value back in

// 两个异步操作  
var todos = [
    function getUser(commit){ 
        setTimeout(() => {
            commit({  // 这里是异步结束的时候 利用 commit 把值回传 
                name: 'eczn',
                age: 20
            }, 233); 
        }); 
    },
    function getLoc(commit){
        setTimeout(() => {
            commit({
                area: '某个地方'
            });
        }, 333); 
    }
]; 

Writing a launcher

Processors are data like todos. cb is the final callback.

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

    processors.forEach((func, idx) => {
        func(function commit(asyncVal){ // 这就是commit函数 
            // 把 asyncVal 的所有属性合并到 o 上 
            // ( 利用 Object.keys 获取对象全部属性名 )
            Object.keys(asyncVal).forEach(key => {
                o[key] = asyncVal[key]; 
            }); 
            
            // 计数器自加 
            count++; 
            // 如果发射器全部发射完毕则调用回调函数 cb 并把 o 作为参数传递
            if (count === processors.length) cb(o); 
        }); 
    }); 
}

Concurrent them

Execute an asynchronous emitter and provide final callback

launcher(todos, function(whereEczn){
    // todos 里面存放的异步操作的值由 commit 回调返回
    // 全部回调跑完的时候 就会执行当前这段函数 并把期望值返回
    console.log(whereEczn); 

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

Link

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

世界只因有你

You can define a variable a=0, and set a++ in the callback after the ajax request is successful;
Then judge a==2 in both callbacks and execute the operation function

Peter_Zhu

Set two flags, and then two ajax call the same callback. In this callback, it is judged that both flags are true before subsequent operations are performed.

漂亮男人

Write ajax in another ajax and execute it in the callback

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template