Закрытие Javascript не соответствует ожиданиям. (Atmoic значение не поддерживается внутри закрытия) - PullRequest
2 голосов
/ 03 апреля 2019

Я сталкиваюсь с проблемой, когда пытаюсь использовать замыкание для сохранения значения, которое я использую при обратном вызове из асинхронной функции.

Основной порядок операций для функций:

  1. Я пытаюсь использовать Google для маршрутизации через несколько точек одновременно. Так что маршрут от x-> y-> z за один звонок

  2. Если это не удается, тогда маршрутизация разбивается на отдельные вызовы и маршрутизируется через каждый из них. Итак, x-> y, а затем y-> z.

Проблема заключается во второй части. В одиночной маршрутизации вызывается функция, которая является синхронной функцией, которая приводит к другой синхронной функции, которая приводит к асинхронной функции. Затем, когда он завершает свою работу, он использует обратные вызовы для возврата к исходной функции.

Так, например: w будет x, который будет называть y, который будет называть z (что является асинхронным). Тогда z перезвонил бы y, который перезвонил бы x. Однако когда я возвращаюсь в x, я знаю, что область действия w исчезла. Однако, используя замыкание, я ожидал, что смогу сохранить эти значения. Тем не менее, я все еще получаю классическую проблему исправления замыканий, когда я получаю только окончательное значение, которое было объявлено определенным значением.

Используется код JavaScript ES5. К сожалению, моя компания не достигла того уровня, когда мы можем использовать babel для компиляции на ES6, поэтому необходимо решение ES5. Я использую jquery и попытался переместить замыкание на обратный вызов таким образом:

    DatabaseController.getSingleRoute(routingInfo, (function() {
        var testVal = Math.random() 
        return function(result,resultStatus){
            console.log(testVal) // still always the same value
    }())

Я чувствую, что упускаю что-то простое здесь, но не могу понять, что происходит.

Мне также кажется, что я должен заметить, что я также изменил код, чтобы использовать несколько экземпляров класса GetSingleRouteHelper вместо одного, и установил все значения в переменные класса, поэтому устанавливая this.testVal = Math.random () в каждом экземпляре. Тем не менее, по возвращении из callbakcs значение каждого класса все равно приводит к точно такому же значению.

ПРИМЕЧАНИЕ: Math.random () - это просто то, что я добавил туда, чтобы попытаться проверить мои значения. Это не имеет никакого отношения к фактической информации, которую я пытаюсь передать (значения широты и долготы). Так что я не могу просто переместить Math.random () в обратный вызов.

    MapsController.getMultipleRoute(requests, function(res, status){
        // this would mean it has failed to get the route via multiple waypoints
        if (!status){
            // break up each request into individual requests
            for(var j = 0; j < results; j++){
                GetSingleRouteHelper.singleCarRoute(singleRouteInfo)
            }

        }
    }

    GetSingleRouteHelper.singleCarRoute = function(routingInfo){
        // what I have switched to to test. I need several atomic values that are generated in this scope. 
        var testVal = Math.random();
        (function(testVal2){
            console.log(testVal2) // here the value is as expected, is each individual random number that corresponds to the outer scopes "testVal" value
            DatabaseController.getSingleRoute(routingInfo, function(result, 
            resultStatus) {
                console.log(testVal2); // is always the final value that was declared. So if above function is run 10 times it will always be the 10th random number here.
            }
        }(testVal))


    DatabaseController.getSingleRoute(data, callback){
         // verifies some values are expected before sending forward
         ...
         GetSingleRoute.get(data, function(a,b){ 
         // verify integrity of return values
         ...
         callback(a,b)
         });
    }


    GetSingleRoute.get= function (data, callback) {
       $.ajax({
       type: "GET",
       ws: "fetch_location",
       dataType: "json",
       data: data,
       success: function success(res) {
         callback(result, result.status)
       },
    }

Я ожидаю, что в обратном вызове функции DatabaseController.getSingleRoute значение testVal будет правильным случайным числом для области видимости замыкания. Я получаю окончательное значение. Таким образом, если функция была запущена дважды, и первое случайное число было равно .3254, а второе случайное число было равно .2345, то при активном обратном вызове DatabaseController.getSingleRoute журнал оператора console.log регистрирует журналы 0,2345 0,2345 вместо 0,3252 0,2345

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...