javascript - 如何使用 $q.defer 链接 ajax 请求?

标签 javascript angularjs asynchronous request promise

我需要这样做:浏览器必须向服务器发出 N 个请求,请求不能是异步的,下一个请求在先前的请求停止后开始。

我可以写一些function Afor i < N i++并称之为 function A再次递归地执行此操作,但它一点也不美观。另外,这称为回调 hell 。我想要一些更漂亮的解决方案。

我找到了deffered对象。有人说,它可以帮助我逃离回调 hell 。我想要这样的东西。 setTimeout有模拟一个异步请求:

    function foo1(some) {
        debugger;
        setTimeout(function foo1async() {
            debugger;
            deffered.resolve();
        }, 500);
        return deffered.promise;
    }

    function foo2(some) {
        debugger;
        setTimeout(function foo2async() {
            debugger;
            deffered.reject();
        }, 500);
        return deffered.promise;
    }

    function foo3() {
        debugger;
        setTimeout(function foo3async() {
            debugger;
            deffered.resolve();
        }, 500);
        return deffered.promise;
    }

    var deffered;
    function doChain() {
        debugger;
        deffered = $q.defer();
        var promise = deffered.promise;
        promise.then(foo1);
        promise.then(foo2);
        promise.then(foo3);
        promise["finally"](function () {
            debugger;
        });
        deffered.resolve();
    }
  1. 我希望调用 foo1,然后调用 foo1async 并解析延迟对象。
  2. foo2必须被调用,然后foo2async叫做。 3.现在我预计foo3不会启动,因为 defered 在 foo2async 中被拒绝。之后我期望 foo 在 finally 中名为的部分。

实际上,我有这个: foo1 , foo2foo3叫做。然后 foo 进入 finally节称为。然后foo1async , foo2asyncfoo3async调用函数。

我怎样才能得到我所期望的东西?

实际上,我会有这样的东西:

for(var i = 0; i < N; i++) {
    (function (iter) {
        promise.then(function () {
            foo(iter);
        });
    })(i);
}

最佳答案

你这里有一些错误。

首先,您使用 deferred 将基于回调的异步函数转换为基于 Promise 的函数 - 但每个函数都需要自己的 deferred.promise ,因此也需要自己的 deferred。实际上,我更喜欢使用 $q 构造函数:

function fooN(input){
  return $q(function(resolve, reject){
    setTimeout(function(){
      resolve(input + "; some more data");
    }, 500);
  });
}

(您也可以使用var deferred = $q.defer())

fooN 现在返回一个 Promise,因此您不再需要使用 $q.defer()

事实上,如果异步函数已经是基于 Promise 的,例如 $timeout$http,那么您就不需要 deferred 根本,例如:

function fooN(input){
  return $timeout(function(){
    return input + "; some more data";
  }, 500);
})

因此,我们假设 foo1foo2foo3 的实现类似于 fooN - 所有返回的 promise 。

为了使调用顺序进行,您需要链接 promise - 不要将多个处理程序附加到某个根 promise 。

我会为你分解:

function doChain(){
  var foo1Promise = foo1();
  var foo2AfterFoo1Promise = foo1Promise.then(foo2);
  var foo3AfterFoo2Promise = foo2AfterFoo1Promise.then(foo3);

  var promise = foo3AfterFoo2Promise.then(function(finalData){
    return doSomeProcessing(finalData); // if needed
  });

  promise.catch(function(error){
    // "rethrow", if can't handle
    return $q.reject({msg: "Some error occurred"});
  })

  return promise;
}

或者,同样的,更简洁:

function doChain(p){
  return foo1(p)
          .then(foo2)
          .then(foo3)
          .then(function(finalData){
            return doSomeProcessing(finalData);
          })
          .catch(function(error){
            return $q.reject({msg: "Some error occurred"});
          });
}

每个函数的“ promise ”返回值是下一个链接函数的输入。

关于javascript - 如何使用 $q.defer 链接 ajax 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31741698/

相关文章:

javascript - 在工作时间显示/隐藏 div,与 UTC 混合?

javascript - 在 oi-select 中加载大数组在 angularjs 中花费太多时间

javascript - 获取结果未定义(Backbone.js)

c# - 如果你使用 async-await 而你的机器只有 1 个处理器会怎样?

.net - PLINQ 有异步版本吗?

javascript - 损坏的链接 - JQuery 1.9 Js 文件中的 "/a"

javascript - 跨多个文件多次引用 javascript 库的行为是什么?

javascript - Jest 不能使用 js 文件中的 HOC,但可以正确使用 tsx 文件中的 HOC

angularjs - 如何在tomcat中打包和部署Grails 3.3.2 Angular项目

angularjs - 使用 Restangulars extendModel 添加的函数未定义?