JS Promise无法返回结果

时间:2014-09-01 03:37:29

标签: javascript google-maps

我正在尽我所能让我的JS承诺工作,但它无法返回任何结果。

geocodeAddress = function(streetAddress){

    var geocodeObject = new Promise(function(resolve, reject) {

      // async call to Google's Geocoder - takes street address
      // and returns GPS coordinates

      var gpsPosition = {};
      geocoder = new google.maps.Geocoder();
      if (geocoder) {
        // console.log("This is the street address");
        // console.log(streetAddress);
        geocoder.geocode({'address': streetAddress}, function(results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
            if (results[0]) {
              console.log("got GPS coordinates for the streetAddress!");
              gpsPosition.B = results[0].geometry.location['B'];
              gpsPosition.k = results[0].geometry.location['k'];
              console.log(gpsPosition);
              resolve(gpsPosition);
            } else {
              alert("No results found");
              reject(Error("It broke"));
            }
          } else {
            alert("Geocoder failed due to: " + status);
            reject(Error("It broke"));
          }
        });
      }

    });

    geocodeObject.then(function(result) {
      console.log("This is the gpsPosition");
      console.log(result); // this console logs the result just fine
      return result;       // however the result can't be returned
    }, function(err) {
      console.log(err); // Error: "It broke"
    });

}

如果我geocodeAddress("1600 Amphitheatre Pkwy, Mountain View, CA 94043")该函数能够console.log结果,但无法在下一行返回它。

我一直在使用这些作为承诺的参考:

http://www.html5rocks.com/en/tutorials/es6/promises/#toc-javascript-promises

http://www.sitepoint.com/overview-javascript-promises/

但是这些教程(至少是第二篇)的问题在于它们从不显式返回结果。他们要么控制台记录它(可以工作),要么立即在函数内使用它。

2 个答案:

答案 0 :(得分:1)

对于任何类型的异步调用,您需要使用回调函数处理结果,而不是查找async函数来返回值。原因在于异步操作的本质......线程需要能够移动到下一个任务并在完成时使用回调函数处理异步操作的结果。异步操作可以返回异步操作结果的唯一方法是,如果计算机保持在异步线程上直到它完成,这将使它成为同步操作。看看这是否有帮助:

function geocodeAddress(streetAddress) {

    new Promise(function(resolve, reject) {

      // async call to Google's Geocoder - takes street address
      // and returns GPS coordinates

      var geocoder = new google.maps.Geocoder();
      geocoder.geocode({'address': streetAddress}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          if (results[0]) {
            resolve({B: results[0].geometry.location['B'],
                     k: results[0].geometry.location['k']});
          } else {
            reject(Error("It broke"));
          }
        } else {
          reject(Error("It broke"));
        }
      });
    })
    .then(
      // this is the Promise resolve handler
      function(result) {
        handleGeocodeResult(result);
      },
      // this is the Promise reject handler
      function(err) {
        console.log(err); // Error: "It broke"
      });
}

function handleGeocodeResult(result) {
  // for illustration only... this function should actually
  // *BE* the Promise resolve handler.
  console.log("This is the gpsPosition");
  console.log(result); // this console logs the result just fine
}

geocodeAddress("1600 Amphitheatre Pkwy, Mountain View, CA 94043");

<强> JSFiddle

答案 1 :(得分:0)

问题在于您使用geocodeAddress功能的方式。你期待着承诺在下一行返回。你应该做的是从geocodeAddress返回承诺,并将其用作承诺。

geocodeAddress = function(streetAddress){

  // sorry i omitted the resolve here, for clarity, here more explicit:
  var geocodeObject = new Promise(function (resolve, reject) {
      resolve('hello world');
  });

  // return the promise
  return geocodeObject.then(function() {});
};

// use the geocodeAddress as a promise
var geoAddressPromise = geocodeAddress('alasjdf');

// see geoAddressPromise is a promise object, you can't console log the result.
// you can call 'then' method on it.

geoAddressPromise.then(function(result) {
   // put your code here instead of the next line.
   // you can console.log the result here
   console.log(result);

   // this result is the value you pass to 'resolve' callback inside the promise.
   // in this example it s "hello world".
});