我希望能够链接promises以使代码同步。我的问题是,根据第一个$ http请求的结果,我可能想要发送另一个或不。
如果我选择不发送另一个$ http请求,我不需要我的第二个then()
做任何事情。但是因为我的第二个then()
并不知道这一切,所以它仍然挂在那里,所以我想我需要先从一个假的假承诺回来。但我还想在第二个()中认识到这个案例。我想出了从第一个案例中返回$ q.when('some value')。这是代码:
$http.get(url, params)
.then(function(res) {
res = res.data;
if (res.status == 'ok' && res.rows.length > 0) {
$scope.roomTypes = res.rows;
return $q.when({ isDummy: true }); //in this case I don't need to send another request
} else if (res.rows.length === 0 && $scope.request.roomType) {
return $http.get(url2, params2); //make second request and return then`able promise
}
}, function(res) {
throw 'Error';
})
.then(function(res) {
res = res.data;
if (res.status == 'ok') {
var roomType = {
room_type: res.roomType.id,
description: res.roomType.description
};
$scope.roomTypes.push(roomType);
} else if (res.isDummy) {
//ok that's our dummy promise
} else {
//format of response unexpected it means something went wrong
throw "error";
}
}, funcrtion(res) {
throw "some Error";
})
.catch(function(res) {...})
.finally(function() {...});
问题是我希望看到解决了承诺的价值({isDummy:true}),但我该怎么做?我在undefined
参数中得到res
。
答案 0 :(得分:1)
res
将在此处未定义
.then(function(res) {
res = res.data;
...
因为data
对象上没有{isDummy: true}
属性。
答案 1 :(得分:1)
我认为这里的基本问题是将承诺与承诺处理程序混淆。成功处理程序应该返回一个值,而不是另一个promise。当你在一个promise成功处理程序中时,你会被promise机制“包装”,它会将你返回的值传递给下一个处理程序。这意味着你的第二个承诺没有看到初始响应,而是第一个承诺返回的内容。
除非按原样传递值,否则将继续处理该值。
例如 这一切都来自你的行
return $q.when({isDummy: true});
应该是
return {isDummy: true};
问题是另一种情况,您希望继续下一个查询。我可能会做以下其中一项: 1.从第一个承诺开始处理(使用第一个处理程序中的相关逻辑)。 2.传递url2和params - 返回({url:url2,params:params})并在第二个承诺中处理它们。
请注意,如果任何处理程序拒绝,则承诺通道甚至可以在中间中断,不会调用成功处理程序here is a simple example(确保打开devtools控制台以查看日志)。
答案 2 :(得分:0)
尝试返回除promise或deferred之外的任何对象:)并将其值传递给then
。像这样:
return { isDummy: true };
示例代码:https://jsfiddle.net/817pwvus/
来自jQuery when
documentation:
如果将单个参数传递给jQuery.when()并且它不是Deferred或Promise,则它将被视为已解决的Deferred,并且将立即执行任何附加的doneCallbacks。 doneCallbacks传递原始参数。
答案 3 :(得分:0)
如果你想要代码同步,你总是可以先写一个长代码块。
如果你想链接承诺(帖子:url1) - >(帖子:url2)等等:
1.回归无用。 2.假设你有2个$ http承诺你想要链接,例如,来自名为$ users的服务,他们调用GetUserAge和GetRelevantBars,第二个查询基于第一个查询#s; s结果
angular
.module("moduleA")
.controller("exmapleCtrl",exampleCtrl);
exampleCtrl.$injector=["$users"];
function exampleCtrl($users){
var vm=this;
vm.query = $users.GetUserAge().then( /*OnSuccess*/ GetUserAgeCB)
//Callback of the GetUserAgeCB;
function GetUserAgeCB(result){
$users.GetRelevantBars().then( /*OnSuccess*/ GetRelevantBarsCB);
/*continuation of CallBack code*/
}
//Callback of the GetRelevantBarsCB;
function GetRelevantBarsCB(result){
/*CallBack code*/
}
}
希望这是可以理解的..
答案 4 :(得分:0)
您应该将第二个处理程序仅嵌套并附加到需要它的promise:而不是返回虚拟值并明确忽略该值:
$http.get(url, params)
.then(function(res) {
var data = res.data;
if (data.status == 'ok' && data.rows.length > 0) {
$scope.roomTypes = data.rows;
return; // do nothing
} else if (res.rows.length === 0 && $scope.request.roomType) {
return $http.get(url2, params2)
.then(function(res) {
var data = res.data;
if (data.status == 'ok')
$scope.roomTypes.push({
room_type: data.roomType.id,
description: data.roomType.description
});
else
throw "error"; //format of response unexpected it means something went wrong
});
}
})
.catch(function(res) {…})
.finally(function() {…});