异步设置变量使用promise并避免回调

Async set variable using a promise and avoiding callbacks

本文关键字:回调 promise 设置 变量 异步      更新时间:2023-09-26

在Angular(和其他JavaScript框架)中,http请求中的数据使用promise异步检索,并可以使用回调设置为变量。很简单。但我已经厌倦了写这样的代码:

service.getWidgetsAsync(function (result) { vm.widgets = result.data });

我有没有想过要把上面的内容写得更像这样。。。。?

vm.widgets = service.getWidgetsAsync();

"否"可能是一个有效的答案。:-)

(添加getWidgetsAsync以澄清的示例:)

function getWidgetsAsync(callback) {
    $http.get(APPBASEURL + 'Foo/GetWidgets')
        .then(function(result) {
            callback(result);
        });
}

问题是,通过涉及回调,您正在破坏承诺的全部要点。返回promise,而不是使用它来调用回调:

function getWidgetsAsync() {
    return $http.get(APPBASEURL + 'Foo/GetWidgets');
}

然后你可以写这样的代码:

service.getWidgetsAsync()
.then(function (result) {
    vm.widgets = result.data;
    // do more stuff with vm.widgets
})
.then(/* do other things after the function above is done */);

你的问题的答案是否定的,你不能在调用异步操作后立即使用它的结果。如果可以,它就不会是异步的。

是和否…您可以使用angular $resource,它最初会用一个空对象填充变量,并在得到结果时填充详细信息,这样您的代码看起来就像您想要的一样,但直到调用完成才会填充值,因此您不能立即假设您有数据。

angular.module('MyApp')
    .factory('WidgetResource', ['$resource', function ($resource) {
        return $resource('/api/widgets',
          { 
            'get':    {method:'GET'},
            'save':   {method:'POST'},
            'query':  {method:'GET', isArray:true},
            'remove': {method:'DELETE'},
            'delete': {method:'DELETE'}
          });
    }]);

然后在您的控制器中:

var vm.widgets = WidgetResource.query();

您所做的任何绑定或监视都将在收到数据时触发。例如,如果您在ng-repeat中有一个小部件列表,它们将在ajax调用完成时显示,但如果您在代码中的上面一行之后立即检查小部件数组的长度,它将为零。