AngularJS $q.all & multiple $q.defer

时间:2022-12-04 15:10:41

Even though I have managed to make my code work, there is something I don't understand. The following piece of code functions correctly:

虽然我已经设法使我的代码工作,但有一些我不明白的东西。以下代码正常运行:

socket.on('method', function() {
    var payload = {
      countrycode: '',
      device: ''
    };
    var d1 = $q.defer();
    var d2 = $q.defer();
    $q.all([
      geolocation.getLocation().then(function(position) {
        geolocation.getCountryCode(position).then(function(countryCode){
          payload.countrycode = countryCode;
          d1.resolve(countryCode);
        });
        return d1.promise;
      }),
      useragent.getUserAgent().then(function(ua) {
        useragent.getIcon(ua).then(function(device) {
          payload.device =  device;
          d2.resolve(device);
        });
        return d2.promise
      })
    ]).then(function(data){
      console.log(data); //displays ['value1', 'value2']
    })
  });

Is there a better way of achieving this? Before I had only one deferred variable, i.e. varvar deferred = $q.defer(); but that way the .then() function returned an object with double the results.

有没有更好的方法来实现这一目标?在我只有一个延迟变量之前,即varvar deferred = $ q.defer();但是那样.then()函数返回一个结果加倍的对象。

So the few question I have are:

所以我的几个问题是:

  1. Do I need multiple $q.defer vars?
  2. 我需要多个$ q.defer变量吗?
  3. Is the above the best way to wait for two async calls to finish and populate the payload object?
  4. 以上是等待两个异步调用来完成和填充有效负载对象的最佳方法吗?

3 个解决方案

#1


6  

socket.on('method', function() {
    var payload = {
      countrycode: '',
      device: ''
    };
    geolocation.getLocation()
    .then(function(position) {
      return geolocation.getCountryCode(position);
    })
    .then(function(countryCode) {
      payload.countrycode = countryCode;
      return useragent.getUserAgent();
    })
    .then(function(ua) {
      return useragent.getIcon(ua);
    })
    .then(function(device) {
      payload.device =  device;
      console.log(data); //displays ['value1', 'value2']
    });
});

read the promise chaining part

阅读承诺链条部分

#2


6  

You could always separate your code into smaller semantic blocks like so:

您总是可以将代码分成较小的语义块,如下所示:

getCountryCode = function() {
  var d = $q.defer();
  geolocation.getLocation()
  .then(function(position) {
    return geolocation.getCountryCode(position)
  })
  .then(function(countryCode) {
    d.resolve(countryCode);
  })
  .fail(function(err) {
    d.reject(err);
  })
  return d.promise;
};

getDevice = function() {
  var d = $q.defer();
  useragent.getUserAgent()
  .then(function(ua) {
    return useragent.getIcon(ua)
  })
  .then(function(device) {
    d.resolve(device);
  })
  .fail(function(err) {
    d.reject(err);
  });
  return d.promise;
}

That will shorten your actual parallel call ($q.all) quite a bit:

这会缩短你的实际并行调用($ q.all):

socket.on('method', function() {
  $q.all([getCountryCode(), getDevice()])
    .spread(function(countryCode, device) {
      var payload = {
        countryCode: countryCode,
        device: device
      };
      // ... do something with that payload ...
    });
});

#3


0  

To synchronize multiple asynchronous functions and avoid Javascript callback hell: http://fdietz.github.io/recipes-with-angular-js/consuming-external-services/deferred-and-promise.html

要同步多个异步函数并避免Javascript回调地狱:http://fdietz.github.io/recipes-with-angular-js/consuming-external-services/deferred-and-promise.html

#1


6  

socket.on('method', function() {
    var payload = {
      countrycode: '',
      device: ''
    };
    geolocation.getLocation()
    .then(function(position) {
      return geolocation.getCountryCode(position);
    })
    .then(function(countryCode) {
      payload.countrycode = countryCode;
      return useragent.getUserAgent();
    })
    .then(function(ua) {
      return useragent.getIcon(ua);
    })
    .then(function(device) {
      payload.device =  device;
      console.log(data); //displays ['value1', 'value2']
    });
});

read the promise chaining part

阅读承诺链条部分

#2


6  

You could always separate your code into smaller semantic blocks like so:

您总是可以将代码分成较小的语义块,如下所示:

getCountryCode = function() {
  var d = $q.defer();
  geolocation.getLocation()
  .then(function(position) {
    return geolocation.getCountryCode(position)
  })
  .then(function(countryCode) {
    d.resolve(countryCode);
  })
  .fail(function(err) {
    d.reject(err);
  })
  return d.promise;
};

getDevice = function() {
  var d = $q.defer();
  useragent.getUserAgent()
  .then(function(ua) {
    return useragent.getIcon(ua)
  })
  .then(function(device) {
    d.resolve(device);
  })
  .fail(function(err) {
    d.reject(err);
  });
  return d.promise;
}

That will shorten your actual parallel call ($q.all) quite a bit:

这会缩短你的实际并行调用($ q.all):

socket.on('method', function() {
  $q.all([getCountryCode(), getDevice()])
    .spread(function(countryCode, device) {
      var payload = {
        countryCode: countryCode,
        device: device
      };
      // ... do something with that payload ...
    });
});

#3


0  

To synchronize multiple asynchronous functions and avoid Javascript callback hell: http://fdietz.github.io/recipes-with-angular-js/consuming-external-services/deferred-and-promise.html

要同步多个异步函数并避免Javascript回调地狱:http://fdietz.github.io/recipes-with-angular-js/consuming-external-services/deferred-and-promise.html