web-dev-qa-db-ja.com

JavaScriptでコールバックを待つ

私はコールバックの情報を持つオブジェクトを返す関数を作成しようとしています:

var geoloc;

var successful = function (position) {
    geoloc = {
        longitude: position.coords.longitude,
        latitude: position.coords.latitude
    };
};

var getLocation = function () {
    navigator.geolocation.getCurrentPosition(successful, function () {
        alert("fail");
    });

    return geoloc;
};

これどうやってするの?関数getLocationは、successfulが実行される前にnull値を返します。

ありがとう!

20
palvarez89

関数は非同期であるため、コールバックが使用されます。コールバックは将来のある時点で実行されます。

そのため、コールバックがトリガーされる前にyes getLocationが戻ります。それが非同期メソッドの仕組みです。

コールバックを待つことはできません。それが機能するわけではありません。 getLocationにコールバックを追加できます。コールバックが完了すると実行されます。

_var getLocation = function(callback){
    navigator.geolocation.getCurrentPosition(function(pos){
        succesfull(pos);
        typeof callback === 'function' && callback(geoloc);
    }, function(){
        alert("fail");
    });
};
_

var x = getLocation()を実行して戻り値を期待する代わりに、次のように呼び出します:

_getLocation(function(pos){
    console.log(pos.longitude, pos.latitude);
});
_
25
Rocket Hazmat

ロケットの答えでアプローチをお勧めします。ただし、本当に必要な場合は、jQuery遅延オブジェクトを使用して、getLocationが終了したときに残りのコードをトリガーできます。これにより、getCurrentPositionで提供されるコールバックを使用するよりもきめ細かな制御が可能になります。

// create a new deferred object
var deferred = $.Deferred();

var success = function (position) {
    // resolve the deferred with your object as the data
    deferred.resolve({
        longitude: position.coords.longitude,
        latitude: position.coords.latitude
    });
};

var fail = function () {
    // reject the deferred with an error message
    deferred.reject('failed!');
};

var getLocation = function () {
    navigator.geolocation.getCurrentPosition(success, fail); 

    return deferred.promise(); // return a promise
};

// then you would use it like this:
getLocation().then(
    function (location) {
         // success, location is the object you passed to resolve
    }, 
    function (errorMessage) {
         // fail, errorMessage is the string you passed to reject
    }); 
20
jbabey