我试图了解JavaScript中的承诺(特别是AngularJS)。
我在服务中有一个函数,我们称之为fooService
,它检查我们是否加载了一些数据。如果有,我只想让它返回,如果我们没有,我们需要加载数据并返回一个承诺:
this.update = function(data_loaded) {
if (data_loaded) return; // We've loaded the data, no need to update
var promise = Restangular.all('someBase').customGet('foo/bar').then(function(data) {
// Do something with the data here
}
return promise;
}
我有另一个函数,然后调用update
的{{1}}函数,如下所示:
fooService
我的问题是,如果我们不需要在fooService.update(data_loaded).then(function() {
// Do something here when update is finished
})
函数中加载数据,则不会返回承诺,因此在我的其他函数中不会调用update
。这里的方法应该是什么 - 基本上我想立即从.then()
函数返回一个已解决的承诺,如果我们不需要从Restangular调用中获取数据?
答案 0 :(得分:43)
由于您的承诺使用与JavaScript本机相同的语法,您可以使用并返回已经解析的JavaScript承诺:Promise.resolve()
return(Promise.resolve("MyReturnValue"));
答案 1 :(得分:27)
当前接受的答案过于复杂,并滥用deferred anti pattern。这是一个更简单的方法:
this.update = function(data_loaded) {
if (data_loaded) return $q.when(data); // We've loaded the data, no need to update
return Restangular.all('someBase').customGet('foo/bar')
.then(function(data) {
// Do something with the data here
});
};
或者,甚至更进一步:
this._updatep = null;
this.update = function(data_loaded) { // cached
this._updatep = this._updatep || Restangular.all('someBase') // process in
.customGet('foo/bar'); //.then(..
return this._updatep;
};
答案 2 :(得分:6)
AngularJS的$q服务将在这里为您提供帮助。它很像Kris Kowal's Q承诺库。
如果您有可能返回promise或值的异步方法,请使用$q.when方法。它将传递给它,无论是承诺还是价值,并根据传递的承诺创建将被解决/拒绝的承诺,或者在传递值时解决。
$q.when( fooService.update(data_loaded) ).then(function(data){
//data will either be the data returned or the data
//passed through from the promise
})
然后在你的更新函数中返回数据而不是只返回
if (data_loaded) return data_loaded;
答案 3 :(得分:0)
类似于Elo's answer,您可以使用async / await语法返回已解决的Promise:
this.update = async (data_loaded) => {
if (data_loaded)
return await null; // Instead of null, you could also return something else
// like a string "Resolved" or an object { status: 200 }
else
return await OtherPromise();
}
答案 4 :(得分:-2)
您可以像这样使用$q.defer()
:
this.update = function (data_loaded) {
var deferred = $q.defer();
if (data_loaded) {
deferred.resolve(null); // put something that your callback will know the data is loaded or just put your loaded data here.
} else {
Restangular.all('someBase').customGet('foo/bar').then(function(data) {
// Do something here when update is finished
deferred.resolve(data);
}
}
return deferred.promise;
};
希望这有帮助。