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

问题描述 投票:1回答:2

我有一个表名数组,所以我需要获取三个表的响应。请参阅以下代码。一旦数据附加到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)
javascript jquery ajax ecmascript-5
2个回答
1
投票

在显示消息之前,您将使用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();
       }
    }
});

这不是我的头脑,可能需要一些调整,但它应该让你以正确的方式前进。


-1
投票

您可以尝试以下代码:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.