2014-01-27 3 views
0

Я даже не уверен, как сформулировать этот вопрос, поэтому мне придется пойти с примерами. Это может быть не похоже на полезный код здесь, и действительно, это не так, но это пример проблемы, с которой я только что столкнулся, урезанной до нужной вещи.Javascript: Что происходит со старым объектом при создании нового экземпляра?

Lets' Предположим, у меня есть

function myObject(params) { 

    .. do some time-consuming asynchronous stuff 
     with AJAX and the like ... 

    return (before all the above is completed); 

} 

function myFunction(params) { 

    var doTheSlowStuff = new myObject(params); 

} 

myFunction(firstParams); 
myFunction(moreParams); 

Что происходит с первым MyObject, когда я делаю второй вызов MYFUNCTION()? Получает ли он возможность завершить свою работу (и если да, то будет ли это сбор мусора, когда он есть)? Или он бесцеремонно сбрасывается, прежде чем у него есть шанс закончить то, что он начал?

+0

Оба вызова 'myObject' будут завершены (т. Е. Поведение async действительно произойдет дважды). Я не думаю, что вы включили достаточно информации в этот пример, чтобы точно сказать, будет ли потеряна какая-либо информация, но это вполне возможно. Каждый вызов 'myFunction' создает свою собственную переменную doTheSlowStuff, поэтому будущие вызовы не будут уничтожать' doTheSlowStuff' из другого вызова. Однако, если это значение выходит за рамки «myFunction», все ставки неактивны, и слияние может действительно произойти. – apsillers

+0

Вы можете вернуть обещание от 'myObject' и обработать успех в' myFunction'. – elclanrs

ответ

0

В этом конкретном экземпляре вы создадите два экземпляра myObject, которые будут сохранены в памяти до тех пор, пока ваше приложение не выйдет.

Вы можете доказать это, запустив что-то в асинхронном режиме, чтобы проверить это поведение:

function myObject(params) { 

    // do something async, like output 
    // every second ... 
    var callback = function() { 
    console.log("I am object " + params); 
    setTimeout(callback, 1000); 
    }; 
    callback(); 

} 

function myFunction(params) { 

    var doTheSlowStuff = new myObject(params); 

} 

myFunction(1); 
myFunction(2); 
// etc. 

Смотрите рабочий пример по адресу: http://jsbin.com/osEFuWib/1/edit

+0

', пока ваша заявка не выйдет Это интересно. Вы позволили мне пролить свет на мой вопрос. То, что я хочу, чтобы myObject выполнял, состоит в том, чтобы перебирать массив параметров, вызывая либо функции AJAX, либо некоторые другие функции, которые возвращают обещание для каждой ваули в массиве. Мне не нужно возвращать значение из myFunction или myObject. То, что я хочу избежать, - это то, что вы, кажется, предположите, произойдет, - каждый создаваемый myObject останется в памяти, даже когда все асинхронные вещи закончатся. Это так? Если так, мне придется найти другой метод. –

+0

@MarkGreenwood Суть в том, что, если у вас нет ссылок на ваши данные, в конечном итоге это будет мусор. Поэтому нет особых причин, по которым вы * не можете использовать JavaScript для своего голодного приложения. Это может быть не самый подходящий инструмент для этого случая использования, и вам, возможно, придется быть осторожным, чтобы убедиться, что у вас действительно нет утечек, но вы можете использовать JavaScript. Просто убедитесь, что никакая закрытость с вашими данными в области видимости недоступна нигде в DOM, включая обработчики событий, прикрепленные к элементам DOM, или что-либо в глобальной области. Смотрите видео, которое я связал выше. –

+0

@Brian Gordon Спасибо, я думаю, это то, что мне нужно было знать. Это не голодное приложение (пока), и этот вопрос был о том, что я пытался помешать ему стать таким - я не очень хорошо это говорил. –

1

Все трудоемкий асинхронный материал будет происходить асинхронно :)

Это означает, что асинхронные вызовы (такие как XHR или setTimeout) мгновенно возвращаются и позволяют продолжить выполнение. Другими словами, конструктор myObject будет возвращаться очень быстро, поэтому между созданием двух myObjects не будет задержки. После того, как и myFunctions возвращаются, то, наконец, элемент управления вернется в цикл событий, и механизм JavaScript продолжит обработку событий, таких как щелчки мыши, события WebSocket, таймеры, такие как setTimeout или запросы XHR. Ваш асинхронными не будет выполняться до тех пор, пока не вернетесь управления в цикл обработки событий, так что ничего с ума не делать, как

while(true) { 
    // Check XHR status 
} 

Не беспокойтесь о сборке мусора; если у вас есть событие DOM, такое как запрос AJAX (XHR) с вашим объектом myObject, тогда он не будет собирать мусор, пока сам обработчик событий не будет собран с мусором.

0

Асинхронный код имеет доступ к функции обратного вызова . Обратный вызов будет работать и равен независимо от любого другого объекта. «Потеря» объекта или создание нового объекта не изменяет этого. Таким образом, ожидающие асинхронные операции должны быть явно отменены или обратные вызовы должны быть защищены от выполнения нежелательных эффектов при их вызове.

Вещь в объектах в JavaScript проста: до тех пор, пока любой код - включая обратный вызов - может получить доступ к объекту (например, назначается переменной в области видимости, свойство окна или привязан к DOM), они остаются доступными. В противном случае они будут недоступны и будут исправлены в какой-то момент.

+1

Добавлена ​​одна вещь: DOM может также ссылаться на объекты и предотвращать их сбор мусора. Вот отличный разговор о том, как вы можете выявить эти утечки: https://www.youtube.com/watch?v=x9Jlu_h_Lyw –

+0

@BrianGordon Хорошая точка. Я считаю, что только что доступный из кода, но примечание добавлено. – user2864740

Смежные вопросы