我想我可能会遗漏一些关于承诺如何运作的基本原则,因为我似乎从来没有得到我期望的结果,所以希望有人能够纠正我的想法。
在这种情况下,这是一个相对容易的电话。我有一个角度工厂,其中包括从API获取一些数据(调用mongodb)。
由于存在$ http请求(这是异步的),我将http调用包装在$ q函数中,如果成功则返回resolve
,如果错误则返回reject
。
factory.loadLayout = function (layoutName) {
return $q(function(resolve, reject){
$http.get('/api/getlayout/'+layoutName)
.success(function (data) {
layout = data;
console.log("Got " + layout.name);
resolve('OK');
})
.error(function(data,status,headers,config){
reject(new Error( status));
});
});
}
然后我有另一个函数依赖于第一个函数中收集的数据,称为getButtonId,但据我所知,即使它包含在.then
中,它似乎是在承诺得到解决之前召集。
var promise = padArea.loadLayout(layoutName);
promise.then(padArea.getButtonId('A0'));
那么我错过了什么?
==更新== 所以使用q.defer
尝试相同的事情factory.loadLayout = function (layoutName) {
var defer = $q.defer()
$http.get('/api/getlayout/'+layoutName)
.success(function (data) {
layout = data;
console.log("Got " + layout.name);
defer.resolve('OK');
})
.error(function(data,status,headers,config){
defer.reject(new Error( status));
});
return defer.promise;
}
仍然没有按照我的预期工作,并且在http完成之前仍然会调用.then中的函数。
==更新2 == 好吧,所以让它工作(如果我只是在.then内的工厂中调用该函数,它直接调用它,但是,如果我将它包装在下面的函数中,它突然起作用。任何人都可以解释为什么虽然,因为对我而言,将调用包装到函数内部似乎与调用函数没有任何区别。
padArea.loadLayout(layoutName).then(function(result){
padArea.getButtonId('A0')
});
奇怪的是,只要我将第二个调用(.then中的一个)包装起来,我的原始代码就可以了。
答案 0 :(得分:3)
只需使用$http
承诺:
factory.loadLayout = function (layoutName) {
return $http.get('/api/getlayout/'+layoutName)
.success(function (data) {
layout = data;
console.log("Got " + layout.name);
resolve('OK');
})
.error(function(data,status,headers,config){
reject(new Error( status));
});
}
然后使用它......
factory.loadLayout(param).then(function (response) { ... });
或强>
我明白你要做什么。而是创建一个来自$q
factory.loadLayout = function (layoutName) {
var defer = $q.defer();
$http.get('/api/getlayout/'+layoutName)
.success(function (data) {
layout = data;
console.log("Got " + layout.name);
defer.resolve('OK');
})
.error(function(data,status,headers,config){
defer.reject(new Error( status));
});
return defer.promise;
}
答案 1 :(得分:2)
你也可以使用$ q.defer():
deferred = $q.defer();
$http.get('/api/getlayout/'+layoutName)
.success(function (data) {
layout = data;
deferred.resolve("OK");
})
.error(function (data,status,headers,config){
deferred.reject(new Error(status));
})
return deferred.promise;
如果您不只是执行http请求,并且可以控制返回,这可能会更加通用。