使用 promise ajax 加上超时?

use promise for ajax plus timeout?

我正在编写一个脚本,该脚本进行异步调用以获取一堆数组数据(约 50,000 项),使用 requestanimationframe() 对该数据进行多次迭代,然后进行另一个调用并迭代这些结果, 好几次.

我想在完成与前一批的 requestanimationframe 循环后尽快开始迭代来自后续调用的数据。我想要的是在处理第一批时对下一批进行异步调用,然后在 1) 调用 returns 和 2) requestanimationframe( ) 迭代完成。

我正在使用 jquery。如果我在等待 2 ajax 个调用,我会使用 $.when() 和 done()。但是我的第二个条件不是 ajax return。我想避免一些麻烦,比如在满足第一个条件后使用 setInterval() 检查第二个条件。

现在我的代码是这样的:

function doIt(value){
  $.get("bunch/of/data.php", {param:value}, function(data){
    var t;
    var tt = 0;
    function process(){
      if(tt < 3000) {
        requestAnimationFrame(process)
      }
      var now = new Date().getTime();
      tt += (now - (t || now)); // + ms since last frame called
      t = now;
      //...do a bunch of stuff with data
      if(tt >= 3000){
        doIt(newValue)
      }
    }
    process();
  }
}

这导致等待数据调用,然后用它处理,然后等待下一个数据调用等。

显然没有经过测试,但是,我非常有信心此代码可以正常工作

利用 jQuery AJAX 调用 return 承诺这一事实,可以按如下方式实现

var go = function go(initialValue) {
    return new Promise(function (resolve, reject) {
        var doIt = function doIt(value, data) {
            var p = void 0;
            if (value !== initialValue) {
                p = new Promise(function (resolve, reject) {
                    var started = 0;
                    function process(ms) {
                        started = started || ms;
                        var elapsed = ms - started;
                        var done = elapsed >= 3000;
                        if (done) {
                            return resolve();
                        }
                        // do stuff with data
                        requestAnimationFrame(process);
                    }
                    process(0);
                });
            } else {
                p = Promise.resolve();
            }
            if (value > 0) {
                $.ajax("bunch/of/data.php", { param: value })
                .then(function (data) {
                    return p.then(function () {
                        return doIt(value - 50000, data);
                    });
                });
            } else {
                resolve();
            }
        };
        doIt(initialValue);
    });
};
go(123593)
.then(function() {
    console.log('all done');
});

相同的代码仅使用 jQuery(即在 Internet Exploder 中不需要任何 Promise 支持)

var go = function go(initialValue) {
    var allDone = $.Deferred();
    var doIt = function doIt(value, data) {
        var p = void 0;
        if (value !== initialValue) {
            var deferred = $.Deferred();
            var started = 0;
            function process(ms) {
                started = started || ms;
                var elapsed = ms - started;
                var done = elapsed >= 3000;
                if (done) {
                    return deferred.resolve();
                }
                // do stuff with data
                requestAnimationFrame(process);
            }
            process(0);
            p = deferred.promise();
        } else {
            p = $.when();
        }
        if (value > 0) {
            $.ajax("bunch/of/data.php", { param: value })
            .then(function (data) {
                return p.then(function () {
                    return doIt(value - 50000, data);
                });
            });
        } else {
            allDone.resolve();
        }
    };
    doIt(initialValue);
    return allDone.promise();
};
go(123593)
.then(function() {
    console.log('all done');
});