【问题标题】:Convert nested AJAX call to sequential Promises将嵌套的 AJAX 调用转换为顺序 Promise
【发布时间】:2020-07-05 07:11:02
【问题描述】:

我的代码可以按顺序成功运行 AJAX 调用(对我的员工进行粗略的互联网延迟测试):

const start = new Date().getTime();
const testUrl = "our server URL";
const start = new Date().getTime();
$.ajax(testUrl + '?delay=0.0&length=100').done(function(){
  $.ajax(testUrl + '?delay=0.1&length=1000').done(function(){
    $.ajax(testUrl + '?delay=0.2&length=10000').done(function(){
      $.ajax(testUrl + '?delay=0.1&length=100000').done(function(){
        $.ajax(testUrl + '?delay=0.2&length=10000').done(function(){
          $.ajax(testUrl + '?delay=0.1&length=1000').done(function(){
            $.ajax(testUrl + '?delay=0.0&length=100').done(function(){
              $.ajax(testUrl + '?delay=0.1&length=10').done(function(){
                const end = new Date().getTime();
                internetTestTime = end - start;
                console.log('Your internet test time: ' + internetTestTime + 'ms')
                })
            })
          })
        })            
      })
    })
  })
});

我想将其切换为使用按顺序运行的 Promise。以下是目前的进展:

const start = new Date().getTime();
const testSuiteInputs = [
    {delay: 0.5, length: 100},
    {delay: 0.4, length: 500},
    // more tests here
];
let testSequence = Promise.resolve();
testSuiteInputs.forEach(testSuiteInput => {
    // ???? something goes here...
});
testSequence.then(() => {
    const end = new Date().getTime();
    internetTestTime = end - start;
    console.log('Your internet test time: ' + internetTestTime + 'ms')
});

我需要放什么????让这些 Promise 顺序运行?

【问题讨论】:

  • 为了清楚起见,重新措辞,谢谢
  • 尝试在不使用循环的情况下拼出承诺链。

标签: javascript jquery promise es6-promise


【解决方案1】:

嗯,最简单的方法是将.forEach() 循环切换到async 函数内的普通for 循环,然后使用await:

async function run() {
    const start = new Date().getTime();
    const testSuiteInputs = [
        {delay: 0.5, length: 100},
        {delay: 0.4, length: 500},
        // more tests here
    ];
    for (let item of testSuiteInputs) {
        let url = `${testUrl}?delay=${item.delay}&length=${item.length}`;
        let result = await $.ajax(url);
        // process result here
    }
}

run().then(finalResult => {
    console.log("all done");
}).catch(err => {
    console.log(err);
});

要在不使用async/await 的情况下做到这一点,对数组进行异步访问排序的常见设计模式是使用.reduce(),您只需将promise 链接在一起即可:

const start = new Date().getTime();
const testSuiteInputs = [
    {delay: 0.5, length: 100},
    {delay: 0.4, length: 500},
    // more tests here
];

testSuiteInputs.reduce((p, item) => {
    return p.then(() => {
        // when previous ajax call finished, start the next one
        let url = `${testUrl}?delay=${item.delay}&length=${item.length}`;
        return $.ajax(url).then(result => {
            // process individual result here
        });
    });
}, Promise.resolve()).then(finalResult => {
    console.log("all done");
}).catch(err => {
    console.log(err);
});;

【讨论】:

    猜你喜欢
    • 2017-03-22
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 2017-08-08
    • 2017-11-24
    • 2019-05-19
    • 1970-01-01
    相关资源
    最近更新 更多