如何异步调用的函数 [英] How to asynchronously call functions

查看:131
本文介绍了如何异步调用的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对某些功能的列表控制器打电话说

  $ scope.trader = {};$ scope.getUserLocation();
$ scope.searchPaymentMethod($ scope.trader.cityname);
$ scope.getUserCurrency();

和每这些功能使一个HTTP调用来获取一些数据。说 getUserLocation 做到这一点...

  $ scope.getUserLocation =功能(){
    变种dataPromise = locationServiceCustomised.getCurrentLocation();
    dataPromise.then(功能(结果){
        $ scope.trader.cityname = result.countryName;
    });
}

和所有这些功能设置一些值 $ scope.trader 在调用另一个功能被使用。其值

现在如何使一个个异步调用每一个这些功能,使这些职能的工作一个接一个。

我的全code是有点像这样...

  $ scope.trader = {};$ scope.getOfferList =功能(){    如果($ scope.trader.cityname == NULL || $ scope.trader.cityname ==''){
            $ scope.getUserLocation();
        }    $ scope.searchPaymentMethod($ scope.trader.cityname);
    $ scope.getUserCurrency();
}$ scope.getUserLocation =功能(){
    变种dataPromise = locationServiceCustomised.getCurrentLocation();
    dataPromise.then(功能(结果){
        $ scope.trader.cityname = result.countryName;
    });
}$ scope.searchPaymentMethod =功能(国家){
    locationService.paymentMethod({城市名:国家},功能(数据){
        -------一些功能-------
    });
};$ scope.getOfferList();


解决方案

如果您有依赖于从previous异步函数得到的数值异步功能,需要链条与承诺。然后。如果函数可以并行调用,那么你需要使用 $ q.all

在你的情况, searchPaymentMethod 是严格依赖于价值从的getLocation ,而 getUserCurrency 可以并行完成。

  $ scope.getOfferList =功能(){   VAR paymentMethodPromise =
     $ q.when($ scope.trader.cityname)
       。然后(功能(cachedLocation){
          如果(cachedLocation)返回cachedLocation;          返回getUserLocation();
       })
       。然后(功能(位置){
          //缓存,如果需要的话,但更好的服务执行此
          $ scope.trader.cityname =位置;
          返回searchPaymentMethod(位置);
       });   变种currencyPromise = getUserCurrency();   //当一切完成后,计算offerList
   返回$ q.all({
                  PAYMENTMETHOD:paymentMethodPromise,
                  货币:currencyPromise})
            。然后(功能(数据){
               VAR PAYMENTMETHOD = data.paymentMethod,
                   货币= data.currency;               //基于获取offerList
               返回offersList;
            })};

不用说,对于这项工作,期望对所有这些功能(即 searchPaymentMethod getUserLocation 等)返回正确的价值的承诺。作为一个例子, getUserLocation 并没有做到这一点,现在,应改为类似如下:

 函数getUserLocation(){
   返回locationServiceCustomised
           .getCurrentLocation()
           。然后(功能(位置){
             //如果需要处理结果
             返回location.cityName;
           })
}

其他一些注意事项:


  1. 您不必暴露在 $范围的每个功能 - 只公开了需要从视图,例如调用的那些<按钮NG点击=getOfferList()>


  2. 这是更好地离开缓存有或没有决定的服务(即要实现这些功能),并留下一个干净的API的控制器。


I have some list of functions to call in controller say

$scope.trader = {};

$scope.getUserLocation();
$scope.searchPaymentMethod($scope.trader.cityname);
$scope.getUserCurrency();

and each of these functions make an HTTP call to get some data. Say getUserLocation does this...

$scope.getUserLocation = function() {
    var dataPromise = locationServiceCustomised.getCurrentLocation();
    dataPromise.then(function(result) {
        $scope.trader.cityname=result.countryName;
    });
}

and these all functions set some value to $scope.trader whose value is being used in calling another function.

Now how to make one by one Asynchronous call to each of these functions so that these functions work one after another.

My full code is somewhat like this...

$scope.trader = {};

$scope.getOfferList = function() {

    if($scope.trader.cityname == null || $scope.trader.cityname == '') {
            $scope.getUserLocation();
        }

    $scope.searchPaymentMethod($scope.trader.cityname);
    $scope.getUserCurrency();
}

$scope.getUserLocation = function() {
    var dataPromise = locationServiceCustomised.getCurrentLocation();
    dataPromise.then(function(result) {
        $scope.trader.cityname=result.countryName;
    });
}

$scope.searchPaymentMethod = function(country) {
    locationService.paymentMethod({cityname: country}, function(data) {
        ------- Some Functionality-------
    });
};

$scope.getOfferList();

解决方案

If you have asynchronous functions that depend on values obtained from previous asynchronous functions, you need to chain promises with .then. If the functions can be called in parallel, then you need to use $q.all.

In your case, searchPaymentMethod is strictly dependent on value from getLocation, while getUserCurrency can be done in parallel.

$scope.getOfferList = function() {

   var paymentMethodPromise = 
     $q.when($scope.trader.cityname)
       .then(function(cachedLocation){
          if (cachedLocation) return cachedLocation;

          return getUserLocation();
       })
       .then(function(location){
          // cache, if needed, but better do this in a service
          $scope.trader.cityname = location;
          return searchPaymentMethod(location);
       });

   var currencyPromise = getUserCurrency();

   // when all complete, calculate offerList
   return $q.all({ 
                  paymentMethod: paymentMethodPromise,
                  currency: currencyPromise })
            .then(function(data){
               var paymentMethod = data.paymentMethod,
                   currency = data.currency;

               // based on that get offerList
               return offersList;
            })

};

Needless to say, that for this to work, the expectation is for all these functions (i.e. searchPaymentMethod, getUserLocation, etc...) return a promise of the right value. As an example, getUserLocation doesn't do that now, and should be changed to something like the following:

function getUserLocation(){
   return locationServiceCustomised
           .getCurrentLocation()
           .then(function(location){
             // manipulate the result if needed
             return location.cityName;
           })
}

A few other things to note:

  1. You don't need to expose every function on the $scope - expose only the ones that need to be invoked from the View, e.g. <button ng-click="getOfferList()">

  2. It's better to leave the cached-or-not decision to the service (that should implement these functions) and leave a clean API for the controller.

这篇关于如何异步调用的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆