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
});