如何用promise实现这个方法

时间:2015-02-26 20:14:56

标签: javascript asp.net-mvc promise

我如何使用promise等待异步地理编码方法返回结果然后返回true或false?

function LocationValidator(value, element, paras) {
var geocoder = new google.maps.Geocoder();

geocoder.geocode({ 'address': value }, function (results, status) { // called asynchronously
    if (status == google.maps.GeocoderStatus.OK) {
        return true;
    } else {
        return false;
    }
});
}

2 个答案:

答案 0 :(得分:6)

在您现在居住的浏览器世界中,您如何创建自己的承诺,遗憾的是取决于您使用的承诺库。您可以通过以下几种方法创建一个geocode(address)函数,该函数通过承诺返回其结果:

// jQuery promises
function geocode(address) {
    var geocoder = new google.maps.Geocoder();

    var def = $.Deferred();
    geocoder.geocode({ 'address': value }, function (results, status) { // called asynchronously
        if (status == google.maps.GeocoderStatus.OK) {
            def.resolve(results);
        } else {
            def.reject(status);
        }
    });
    return def.promise();
}

// ES6 style (supported by many polyfills, promise libraries and some browsers natively)
// my favorite library is Bluebird which this would work with
function geocode(address) {
    var geocoder = new google.maps.Geocoder();

    return new Promise(function(resolve, reject) {
        geocoder.geocode({ 'address': value }, function (results, status) { // called asynchronously
            if (status == google.maps.GeocoderStatus.OK) {
                resolve(results);
            } else {
                reject(status);
            }
        });
    });
}

两者都可以这样使用,这很简单:

geocode(address).then(function(result) {
    // code here that can use the result
}, function(errStatus) {
    // code here to handle an error
});

注意:您不能进行这样的异步操作并使其进入同步操作。你不能在Javascript中这样做。因此,您必须学习如何使用异步操作进行编程,并且承诺是一种方便的方法。


其他参考资料:

Wrap Google map geocoder.geocode in a Promise

Promises in the Google APIs JavaScript Client Library

How do I convert an existing callback API to promises?

答案 1 :(得分:1)

可以按如下方式“包装”地理编码异步调用 - 假设回调本身的返回值无关紧要。

请注意,不能用于使异步调用同步;但它确实“包装”异步回调以使用promise。

function geocodeWithPromise(data) {
    // Different frameworks provided different methods of creating and
    // using their promise implementation. Eg in jQuery the following would be:
    //   promise = $.Deferred();
    var promise = makePromise();
    geocoder.geocode(data, function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            promise.resolve(results, status);
        } else {
            promise.reject(status);
        }
    });
    return promise;
}

// The call is "synchronous" and a promise is returned immediately - 
// but done/fail are called later as they are [themselves callbacks and]
// part of the asynchronous promise.
geocodeWithPromise({ 'address': value })
  .done(function () { .. })
  .fail(function () { .. });

教程JavaScript Promises: There and back again更详细地解释了承诺,涵盖了ES6风格的承诺。

(正如jfriend一直指出的那样,上面的代码使用了{em>不所需的done/fail - 因为它们可以用then实现 - 并且只能在一些承诺实现,如jQuery。)