Maison  >  Questions et réponses  >  le corps du texte

js est la meilleure façon d'effectuer une nouvelle opération après deux opérations asynchrones AJax

J'ai rencontré une question d'entretien aujourd'hui, c'est-à-dire que s'il y a deux opérations ajax asynchrones sur la page, parce que je ne suis pas sûr de l'ordre d'exécution de ces deux opérations asynchrones, comment puis-je exécuter une nouvelle opération une fois les deux opérations exécutées ? Meilleure Quelle est la méthode ?

J'ai répondu à la première méthode à ce moment-là : imbriquer deux ajax et effectuer de nouvelles opérations dans la fonction de retour du deuxième ajax. Réponse de l'intervieweur : Cette méthode est trop boiteuse.

J'ai donc réfléchi à la deuxième réponse : surveiller les variables locales via le timer setTimeout et m'assurer que les deux opérations asynchrones sont terminées avant d'effectuer une nouvelle opération. Réponse de l'enquêteur : Les performances de cette méthode ne sont pas bonnes. Pouvez-vous penser à une méthode simple et plus raisonnable ?

Je n'y avais pas pensé à l'époque
Alors j'ai posé cette question pour savoir quelle est la meilleure solution ? Bienvenue pour discuter et donner des conseils

世界只因有你世界只因有你2663 Il y a quelques jours1619

répondre à tous(11)je répondrai

  • 学习ing

    学习ing2017-07-05 10:56:02

    1. La promesse enveloppe les opérations ajax asynchrones,
    2. Définir la fonction asynchrone,
    3. Utilisez wait pour attendre la fin de l'acquisition asynchrone des données promises. Cette méthode est simple et efficace. ci-dessous. Je suis trop paresseux pour l'utiliser. Une fois qu'ajax a obtenu les données, utilisez la fonction settimeout pour simuler l'obtention de données. Cette fonction est asynchrone et a le même principe et le même effet.

    //模拟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()

    répondre
    0
  • 漂亮男人

    漂亮男人2017-07-05 10:56:02

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

    répondre
    0
  • 为情所困

    为情所困2017-07-05 10:56:02

    La méthode native prête à l'emploi actuelle dans l'environnement du navigateur est Promise.all.

    Prenons l'exemple de l'appel de ma bibliothèque de cartes Sinomap Demo Pour charger une carte sur cette page, plusieurs demandes doivent être lancées en même temps mais l'ordre de retour ne peut pas être garanti :

    1. Données de terrain en Chine

    2. Données JSON de chaque province

    3. Lorsque plusieurs graphiques sont superposés, plusieurs données JSON dans plusieurs graphiques doivent être renvoyées via différentes interfaces de données...

    La solution est directement dans le déballé http://sinomap.ewind.us/demo/demo.js, exemple :

    // 封装地形 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)
    })

    De cette façon, Promise réalise non seulement le découplage de la logique de rappel, mais réalise également un contrôle de processus asynchrone de base.

    répondre
    0
  • 高洛峰

    高洛峰2017-07-05 10:56:02

    Je viens de voir la méthode when de jquery, alors j'en ai réécrit une pour vous. Ce n'est peut-être pas aussi bon que jquery, mais au moins cela peut obtenir l'effet. Vous pouvez directement entrer le code suivant dans la console pour essayer. aller écrire. Cela m'a pris une demi-heure. .

    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);
    });
    

    répondre
    0
  • 给我你的怀抱

    给我你的怀抱2017-07-05 10:56:02

    Demandez si je peux utiliser jQ. Si oui, dites simplement :

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

    Au fait, voici la référence de la documentation de $.when

    répondre
    0
  • 为情所困

    为情所困2017-07-05 10:56:02

    Je pense que c'est la méthode de Promise, tout ou quelque chose comme ça

    répondre
    0
  • 学习ing

    学习ing2017-07-05 10:56:02

    Votre question est la suivante : il y a trois choses a, b, c. c doit être exécuté une fois a et b terminés.

    Il existe de nombreuses méthodes : comme la méthode de nidification que vous avez évoquée, et la méthode de surveillance violente

    J'ai déjà réfléchi à cette question et voici ma réponse.

    Émetteur asynchrone

    Comment effectuer des opérations asynchrones à l'aide du stockage sur baie

    Notez que les fonctions à l'intérieur ont toutes un paramètre commit , qui est une fonction utilisée pour renvoyer une valeur. Lorsque ajax réussit, transmettez simplement la valeur de retour

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

    Écrire un lanceur

    Les processeurs sont des données comme des tâches. cb est le rappel final.

    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 eux

    Exécuter un émetteur asynchrone et fournir 最终回调

    launcher(todos, function(whereEczn){
        // todos 里面存放的异步操作的值由 commit 回调返回
        // 全部回调跑完的时候 就会执行当前这段函数 并把期望值返回
        console.log(whereEczn); 
    
        // 按顺序输出
        ['name', 'area'].forEach(key => {
            console.log(`${key}: ${whereEczn[key]}`); 
        }); 
    });

    Lien

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

    répondre
    0
  • 世界只因有你

    世界只因有你2017-07-05 10:56:02

    Vous pouvez définir une variable a=0 et définir a++ dans le rappel une fois la requête ajax réussie
    Ensuite, jugez a==2 dans les deux rappels et exécutez la fonction d'opération

     ;

    répondre
    0
  • 天蓬老师

    天蓬老师2017-07-05 10:56:02

    Définissez deux indicateurs, puis deux ajax appellent le même rappel. Dans ce rappel, il est jugé que les deux indicateurs sont vrais avant que les opérations suivantes ne soient effectuées.

    répondre
    0
  • 漂亮男人

    漂亮男人2017-07-05 10:56:02

    Écrivez ajax dans un autre ajax et exécutez-le dans le rappel

    répondre
    0
  • Annulerrépondre