在执行 ajax 调用后附加数据后调用方法

calling a method once the data is appended after executing the ajax calls

我有一个 table 名称数组,因此我需要获取三个 table 的响应。请参阅下面的代码。将数据附加到 dom 后,我需要调用 successMessage 方法,现在我正在使用 setTimeout 如何在这种情况下使用 promise

   let lists = ['table1', 'table2', 'table3']

   lists.map(list => {
       $.ajax({
         url:`${rootUrl}/api/('${list}')`,
         type: 'GET',
         headers: {
             accept: 'application/json'
              },
         success: res => dataDisplay(res),
         error: err => console.log(JSON.stringify(err))
       })
    })

// displaying data
   const dataDisplay = (res) => {
    switch(res.TableName){
      case 'Table1':
       $("#tbl1 p").text(res.TableOriginalName)
       $("#tbl1 .content p").text(res.TableDescription)
       break;
      case 'Table2':
       $("#tbl2 p").text(res.TableOriginalName)
       $("#tbl2 .content p").text(res.TableDescription)
       break;
      case 'Table3':
       $("#tbl3 p").text(res.TableOriginalName)
       $("#tbl3 .content p").text(res.TableDescription)
       break;
     default:
        return
     }
 }
// successfully data appended
 const successMessage = () => alert("data appended successfully")
// calling the success method once data is appended
 setTimeout(successMessage, 3000)

您将使用 Promise.all 等待所有这些请求完成后再显示消息。首先,建立一个承诺数组:

var promises = lists.map(list => $.ajax({
    url:`${rootUrl}/api/('${list}')`,
    type: 'GET',
    headers: {
        accept: 'application/json'
         },
    success: res => dataDisplay(res),
    error: err => console.log(JSON.stringify(err))
}));

然后等待他们完成

Promise.all(promises).then(() => alert("data appended successfully"));

你也可以使用 $.when 来达到同样的目的,但是调用起来很尴尬:

$.when.apply($, promises).done(() => ...);

您在评论中提到 dataDisplay 加载了一堆图像,您需要延迟对 successMessage 的调用,直到这些图像加载完毕。为此,您需要注意图像上的 load 事件。这可能有点松鼠,因为图像可以在您挂钩事件之前加载,所以我们也想使用图像的 complete 标志。沿着这些线的东西:

Promises.all(/*...*/).then(() => {
    // Get all images in the tables we added to
    let imgs = $("#tbl1 img, #tbl2 img, #tbl3 img");

    // Hook up a function to check for completed images when we
    // see a `load` event on any of them, and fire that proactively
    imgs.on("load", checkComplete);
    checkComplete();

    function checkComplete() {
        // Count any incomplete images; remove the handler from any
        // complete image and remove it from our `imgs` set
        let incomplete = 0;
        imgs.get().forEach(img => {
            if (img.complete || img.error) {
                $(img).off("load", checkComplete);
                imgs = imgs.not(img);
            } else {
                ++incomplete;
            }
        });
        if (incomplete == 0) {
            // They're all done!
            successMessage();
       }
    }
});

这超出了我的想象,可能需要一些调整,但它应该能让您朝着正确的方向前进。

您可以试试这个代码:

let tableNames = ['table1', 'table2', 'table3']

let promiseArr = tableNames.map((table) => {
    return new Promise((resolve, reject) => {

        $.ajax({
            url:`${rootUrl}/api/('${list}')`,
            type: 'GET',
            headers: {
                accept: 'application/json'
                 },
            success: (res) => {
                dataDisplay(res);
                resolve(table);
            },
            error: (err) => {
                console.log(JSON.stringify(err));
                reject(table);
            }
          });
    }).catch((e) => {
        // if call to any of the table's url fails
        // it will come here, var 'e' contains
        // that table name, handle here
         console.log(e + " has fails"); return e; 
        });
});

Promise.all(promiseArr).
    then((result) => {
        // this will run regardless of, if call to any table fails 
        console.log("success") 
    })
    .catch((result) => {
        console.log(result + " fails");
    });

这将异步调用 tables,最后到达 Promise.all() 的 then() 即使调用某些 table 失败