【问题标题】:Executing a Javascript function only after the previous function is fully executed [duplicate]仅在前一个函数完全执行后才执行Javascript函数[重复]
【发布时间】:2019-12-05 20:23:12
【问题描述】:

我有 2 个函数,doFirst() 和 doSomethingElse()。现在第一个函数由大约 10 个 AJAX 请求组成,这些请求在检查该过滤器是否被选中的条件下执行。这些 AJAX 请求与 URL 通信,并在各自的数组中保存一组 ID。完成此操作后,必须触发 doSomethingElse() 来绘制结果表。在这一点上,我通过设置超时来执行它们。我想知道一种更好的方法来等待函数完成然后执行下一个函数。任何帮助是极大的赞赏。 谢谢!

            //How I am currently calling the functions:

            doFirst();
            doSomethingElse();



               function doFirst(){
                 var filterArrayTaxSel1 = $("#taxIA span").get().map(el => el.textContent);
                                for (var i = 0; i < filterArrayTaxSel1.length; i++) {
                                    filterArrayTaxSel1[i] = filterArrayTaxSel1[i].replace(" ", "%20");
                                }
                                // taxgroup2 - Selector
                                queryBuilder = filterArrayTaxSel1;
                                //console.log(queryBuilder);
                                console.log(filterArrayTaxSel1);
                                if (filterArrayTaxSel1.length > 0) {
                                    if (filterArrayTaxSel1.length > 0 && filterArrayTaxSel1[0] != "All") {
                                        console.log("I am inside the IF!");
                                        for (var i = 0; i < filterArrayTaxSel1.length; i++) {
                                            var baseURL = "some URL here";
                                            console.log(baseURL);
                                            responses(baseURL);
                                            function responses(baseURL) {
                                                $.ajax({
                                                    url: baseURL,
                                                    type: "get",
                                                    cache: false,
                                                    headers: {
                                                        'Content-Type': 'application/json'
                                                    },
                                                    success: function (data) {
                                                        console.log(data.features.length);
                                                        for (var i = 0; i < data.features.length; i++) {
                                                            if (taxArrayT1.indexOf(data.features[i].properties.taxon_id) == -1) {
                                                                taxArrayT1.push(data.features[i].properties.taxon_id);
                                                            }
                                                        }
                                                        console.log("In the Invertebrate Animals Section 1");
                                                        console.log(taxArrayT1.length);
                                                    }
                                                })
                                            }
                                        }
                                    }
                                    else if (filterArrayTaxSel1[0] == "All") {
                                        console.log("I am inside the IF!");
                                        var baseURL = "some URL here";
                                        console.log(baseURL);
                                        responses(baseURL);
                                        function responses(baseURL) {
                                            $.ajax({
                                                url: baseURL,
                                                type: "get",
                                                cache: false,
                                                headers: {
                                                    'Content-Type': 'application/json'
                                                },
                                                success: function (data) {
                                                    console.log("I am inside the ELSE IF ALLL!");
                                                    console.log(data.features.length);
                                                    for (var i = 0; i < data.features.length; i++) {
                                                        if (taxArrayT1.indexOf(data.features[i].properties.taxon_id) == -1) {
                                                            taxArrayT1.push(data.features[i].properties.taxon_id);
                                                        }
                                                    }
                                                    console.log("In the Invertebrate Animals Section 2");
                                                    console.log(taxArrayT1.length);
                                                }
                                            })
                                        }
                                    }
                                    //Selection 1 Tax Group AJAX Call   Sensitivity ARRAY WITH 0 to Multiple CASES - ENDS.
                                }
     //some more AJAX Calls depending on whether the filter exists
        //End of function
                }



function doSomethingElse(){
//Code to draw the Table using the arrays from the previous function
}

【问题讨论】:

  • 你能分享你的代码吗?
  • 你使用的是纯javascript还是一些库?大多数库返回 Promise 对象,它使您能够链接调用(从第二个开始,仅在第一个完成时)
  • @smartilabs 我正在使用纯 JavaScript 进行编码。不使用任何库。我不完全确定如何使用这些承诺对象。你也可以举个例子吗?
  • @Azhr-M 我刚刚发布了一个示例代码。抱歉开头草率。
  • 使用$.when()

标签: javascript jquery html ajax asynchronous


【解决方案1】:

Promise 对象表示最终完成(或失败) 一个异步操作及其结果值。

这是一个示例,说明如何使用 Promise 对象使异步代码(例如 AJAX 请求)更易于处理。 Promise.all 似乎是帮助您解决问题的好人选。你可以这样做:

const doFirst = () => {
  console.log('Making AJAX requests, please wait..');
  const asyncActions = [
    //Wrap all your async code in a Promise
    new Promise((resolve, reject) => {
      //Resolve some phony data as part of our AJAX request simulation
      setTimeout(() => resolve({
        name: 'Item 1',
        id: 1
      }), 1000)
    }),
    new Promise((resolve, reject) => {
      setTimeout(() => resolve({
        name: 'Item 2',
        id: 2
      }), 4000)
    }),
    Promise.resolve({
      name: 'Item 3',
      id: 3
    })
  ];

  //Since all your async actions are stored in a iterable, we can use
  return Promise.all(asyncActions);
}

const doSomethingElse = values => {
  console.log('Here is the data returned from our AJAX requests:');
  values.forEach(value => {
    console.log(`Name: ${value.name} || ID: ${value.id}`)
  });
}

doFirst().then(doSomethingElse);

【讨论】:

    【解决方案2】:

    Promise 只是一个对象,您可以将一些函数传递给它,它可以完成某些工作,当它完成时,它会调用一个回调函数 - 您可以将其用于进一步的操作。

    您可以在以下位置找到完整文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/prototype

    例如,你有一个函数,它返回 Promise 对象:

    function makeAjaxCall(url, methodType){
       var promiseObj = new Promise(function(resolve, reject){
          var xhr = new XMLHttpRequest();
          xhr.open(methodType, url, true);
          xhr.send();
          xhr.onreadystatechange = function(){
          if (xhr.readyState === 4){
             if (xhr.status === 200){
                console.log("xhr done successfully");
                var resp = xhr.responseText;
                var respJson = JSON.parse(resp);
                resolve(respJson);
             } else {
                reject(xhr.status);
                console.log("xhr failed");
             }
          } else {
             console.log("xhr processing going on");
          }
       }
       console.log("request sent succesfully");
     });
     return promiseObj;
    }
    

    然后您进行多次 ajax 调用:

    let promise1 = makeAjaxCall(URL1, "GET");
    let promise2 = makeAjaxCall(URL2, "GET");
    let promise3 = makeAjaxCall(URL2, "GET");
    

    然后你有一个“监听器”,它等待所有的承诺(ajax 调用)完成:

    Promise.all([promise1, promise2, promise3]).then(function(values) {
      console.log(values);
    });
    

    您有很多关于该主题的文章和文档:

    【讨论】:

      【解决方案3】:

      在您的代码中,您正在使用 jQuery,因此您可以利用它的一些内置方法。您希望基本上跟踪数组中的所有 Ajax 调用,因此当您进行 Ajax 调用时,将它们推送到数组中。然后你可以使用jQuery的$.when()在它们都完成后执行下一步。

      基本思路:

      function firstStep() {
        var requests = []
        var list = [1,2,3]
        for (var i = 0; i < list.length; i++) {
          requests.push($.ajax(...));
        }
        return requests
      }
      
      function secondStep() {
        console.log(arguments)
      }
      
      var requests = firstStep() 
      $.when.apply(undefined, requests).then(secondStep)
      

      如果你没有使用 jQuery,那将是 promise.all 的承诺

      【讨论】:

      • 如果拒绝投票是因为用户说“没有库”,那么 OP 在代码中使用 jQuery,因此该声明不正确。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-30
      • 2019-05-12
      相关资源
      最近更新 更多