AngularJS 将多个值传递给 promise 的成功回调
AngularJS passing more than one value to promise's success callback
我有以下服务方式:
ResourcesService.prototype.list = function ()
{
var deferred = q.defer();
var settings = fetchSettings();
restService.getAll(resourceName, settings)
.then(function (response) {
deferred.resolve(response.data, {
count: response.headers('cr_count'),
total: response.headers('cr_total'),
last: response.headers('cr_last')
});
}, function (error) {
deferred.reject(error.statusText);
});
return deferred.promise;
}
如您所见,我将两个值传递给 deferred.resolve
,它们是 response.data
和一个元数据对象。
在调用堆栈中我有:
//"scenes" is an object that inherits from ResourcesService
scenes
.withLanguage('en-us')
.sort('creation')
.size(2)
.list()
.then(function (firstPage, metadata) {
//firstPage is the "response.data" from previous method
//metadata is undefined, but should be an object with all the values from the headers
});
为什么 metadata
未定义?我调试了 ResourcesService
并且头文件被读取得很好,但是传递的对象作为 deferred.resolve
的参数没有被委托给我的回调函数。
deferred.resolve
是否支持只传递一个参数给回调?我是否必须将此元数据与响应一起放在同一个对象中?
您不能将超过一个参数传递给 then
回调,只有一个是预期和考虑的。但是,您可以做的是用一个对象来解决您的承诺。例如:
ResourcesService.prototype.list = function () {
var settings = fetchSettings();
return restService.getAll(resourceName, settings).then(function (response) {
return {
data: response.data,
metadata: {
count: response.headers('cr_count'),
total: response.headers('cr_total'),
last: response.headers('cr_last')
}
};
}, function (error) {
throw new Error(error.statusText);
});
}
请注意,我还在您的代码中修复了 deferred anti-pattern,您不需要虚拟延迟对象,因为您已经承诺可以 return.
然后你会像这样使用它:
scenes
.withLanguage('en-us')
.sort('creation')
.size(2)
.list()
.then(function (response) {
var firstPage = response.data,
metadata = response.metadata;
});
虽然@dsfq 关于不使用多个参数进行解析是正确的,但如果您使用 q
,您也可以将已解析的值包装在一个数组中并使用 .spread()
而不是 .then()
将它们拆分成多个参数。
创建时间:
.then(function (response) {
// Resolve with a single array
deferred.resolve([response.data, {
count: response.headers('cr_count'),
total: response.headers('cr_total'),
last: response.headers('cr_last')
}]);
}
消耗:
scenes
.withLanguage('en-us')
.sort('creation')
.size(2)
.list()
// .spread() instead of .then()
.spread(function (firstPage, metadata) {
// Works as expected
});
我有以下服务方式:
ResourcesService.prototype.list = function ()
{
var deferred = q.defer();
var settings = fetchSettings();
restService.getAll(resourceName, settings)
.then(function (response) {
deferred.resolve(response.data, {
count: response.headers('cr_count'),
total: response.headers('cr_total'),
last: response.headers('cr_last')
});
}, function (error) {
deferred.reject(error.statusText);
});
return deferred.promise;
}
如您所见,我将两个值传递给 deferred.resolve
,它们是 response.data
和一个元数据对象。
在调用堆栈中我有:
//"scenes" is an object that inherits from ResourcesService
scenes
.withLanguage('en-us')
.sort('creation')
.size(2)
.list()
.then(function (firstPage, metadata) {
//firstPage is the "response.data" from previous method
//metadata is undefined, but should be an object with all the values from the headers
});
为什么 metadata
未定义?我调试了 ResourcesService
并且头文件被读取得很好,但是传递的对象作为 deferred.resolve
的参数没有被委托给我的回调函数。
deferred.resolve
是否支持只传递一个参数给回调?我是否必须将此元数据与响应一起放在同一个对象中?
您不能将超过一个参数传递给 then
回调,只有一个是预期和考虑的。但是,您可以做的是用一个对象来解决您的承诺。例如:
ResourcesService.prototype.list = function () {
var settings = fetchSettings();
return restService.getAll(resourceName, settings).then(function (response) {
return {
data: response.data,
metadata: {
count: response.headers('cr_count'),
total: response.headers('cr_total'),
last: response.headers('cr_last')
}
};
}, function (error) {
throw new Error(error.statusText);
});
}
请注意,我还在您的代码中修复了 deferred anti-pattern,您不需要虚拟延迟对象,因为您已经承诺可以 return.
然后你会像这样使用它:
scenes
.withLanguage('en-us')
.sort('creation')
.size(2)
.list()
.then(function (response) {
var firstPage = response.data,
metadata = response.metadata;
});
虽然@dsfq 关于不使用多个参数进行解析是正确的,但如果您使用 q
,您也可以将已解析的值包装在一个数组中并使用 .spread()
而不是 .then()
将它们拆分成多个参数。
创建时间:
.then(function (response) {
// Resolve with a single array
deferred.resolve([response.data, {
count: response.headers('cr_count'),
total: response.headers('cr_total'),
last: response.headers('cr_last')
}]);
}
消耗:
scenes
.withLanguage('en-us')
.sort('creation')
.size(2)
.list()
// .spread() instead of .then()
.spread(function (firstPage, metadata) {
// Works as expected
});