我需要这样做:浏览器必须向服务器发出 N 个请求,请求不能是异步的,下一个请求在先前的请求停止后开始。
我可以写一些function A
与 for 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();
}
- 我希望调用 foo1,然后调用 foo1async 并解析延迟对象。
-
foo2
必须被调用,然后foo2async
叫做。 3.现在我预计foo3
不会启动,因为 defered 在foo2async
中被拒绝。之后我期望 foo 在finally
中名为的部分。
实际上,我有这个:
foo1
, foo2
和foo3
叫做。然后 foo 进入 finally
节称为。然后foo1async
, foo2async
和foo3async
调用函数。
我怎样才能得到我所期望的东西?
实际上,我会有这样的东西:
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);
})
因此,我们假设 foo1
、foo2
和 foo3
的实现类似于 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/