【问题标题】:Angular return promise from httpBackend.when()来自 httpBackend.when() 的角度返回承诺
【发布时间】:2018-09-14 22:48:20
【问题描述】:

如何从 httpBackend.when() 返回一个承诺?我想加载一些存储在 .json 文件中的罐头数据并从 httpBackend.whenGET() 返回。当我尝试从 http.get('mydata.json') 返回承诺时,响应将返回到工厂的失败回调。

function getAvailablePackagesComplete(response) {
    return response.data;
}

function getAvailablePackagesFailed(error) { // {error = Object {data: undefined, status: 0, config: Object, statusText: ""}
    $log.error(error.data.description);
    return false;
}

function getAvailablePackages() {
    return $http.get('/1.0/get-available-packages')
    .then(getAvailablePackagesComplete)
    .catch(getAvailablePackagesFailed)
}


var data = {"package": "test", "version": "1"}
$httpBackend.whenGET('/1.0/get-available-packages').respond(function(method, url, data) {
    // return [200,data, {}] // this works
    return $http.get('app/home/fixtures/mydata.json'); // contains {"package: "test", "version": "1"}
}); //this doesn't work

【问题讨论】:

    标签: angularjs angular-promise angular-mock


    【解决方案1】:

    目前,$httpBackend(来自 ngMockE2E)确实支持其 .respond 中的承诺 - 请参阅 AngularJS GitHub Issue #11245。因为$httpBackend应该用来避免发出真正的HTTP请求,但是你可以让一些请求通过。

    来自AngularJS Docs

    此实现可用于通过 when api 及其快捷方式(whenGET、whenPOST 等)以静态或动态响应进行响应,并且可选地将请求传递给真正的 $httpBackend 以获取特定请求(例如与某些远程 API 交互或从网络服务器获取模板)。

    要解决您想要做的事情,您可以尝试让getAvailablePackages() 返回您的 json 文件路径的 HTTP GET 并定义一个 $httpBackend.whenGET('pathTo.json').passThrough();

    【讨论】:

    • 我想保持模拟后端与请求分离,所以当实际 api 准备好时,我可以将模块作为依赖项删除。所以,我认为我必须在模拟后端模块中对数据进行硬编码。
    【解决方案2】:

    我遇到了同样的问题,我的用例是在 JS 中构建我的整个 API 的模拟,以便其他人可以离线工作并开发 UI。

    为了实现这一点,我开发了一个名为 angular-mocks-async 的插件,它装饰了 httpBackend 并向其中添加了 .whenAsync( ) APi。比您可以轻松地模拟响应并返回承诺,如下所示:

    var app = ng.module( 'mockApp', [
        'ngMockE2E',
        'ngMockE2EAsync'
    ]);
    
    app.run( [ '$httpBackend', '$q', function( $httpBackend, $q ) {
    
        $httpBackend.whenAsync(
            'GET',
            new RegExp( 'http://api.example.com/user/.+$' )
        ).respond( function( method, url, data, config ) {
    
            var re = /.*\/user\/(\w+)/;
            var userId = parseInt(url.replace(re, '$1'), 10);
    
            var response = $q.defer();
    
            setTimeout( function() {
    
                var data = {
                    userId: userId
                };
                response.resolve( [ 200, "mock response", data ] );
    
            }, 1000 );
    
            return response.promise;
    
        });
    
    }]);
    

    【讨论】:

      【解决方案3】:

      您可以从 http 拦截器返回 Promise。这是一个将 HTTP 调用延迟 1 秒的示例。您可以将其添加到您的app.config(....)

      $httpProvider.interceptors.push(function($q, $timeout) {
          return {
              'response': function(response) {
                  var defer = $q.defer();
                  $timeout(function() {
                              defer.resolve(response);
                      }, 1000);
                  return defer.promise;
              }
          };
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-31
        • 1970-01-01
        相关资源
        最近更新 更多