Может ли эта функция собираться мусором?

Рассмотрим этот кусок торта... ehm, code:

'use strict'

function doWork () {
  return new Promise(function (resolve, reject) {
    // work work work...
    // Done! But... where the resolve() ???
  })
}

doWork().then(function doMoreWork () {
  // Some more work to do...
})

Как только функция в конструкторе Promise заканчивается...

  • Является ли объект Promise сборкой мусора?
  • Является ли doMoreWork() сборщиком мусора?

Я предполагаю, что doMoreWork() не может быть GC-ed напрямую, потому что Promise сохраняет ссылку на него, но как только тело обещания закончит и вернет контекст выполнения в верхнюю (?) область, стек раскрутится (потому что там больше нет заявлений, которые должны исполняться), и Обещание становится недостижимым, таким образом, будучи сборщиком мусора.

Можете ли вы подтвердить, что мое понимание этой темы верное?

Как я мог эмпирически наблюдать это поведение? Другими словами, как я могу контролировать, какие объекты GC-ed и когда? Я развиваюсь исключительно в Node.js, если это имеет значение.

Ответ 1

Нет никакой ссылки на обещание, так что это будет сбор мусора. Обещание - это единственное, что касается ссылки на функцию doMoreWork, поэтому она также будет собрана мусором.

Как я мог эмпирически наблюдать это поведение? Другими словами, как я могу контролировать, какие объекты GC-ed и когда? Я развиваюсь исключительно в Node.js, если это имеет значение.

GC в V8 никогда не обязательно собирает объект. Например, если это ваша целая программа, это будет пустая трата времени для запуска любого GC в первую очередь.

Ответ 2

  • Объект Promise доступен для коллекционирования, если у него нет ссылок, указывающих на него. Если используется doWork().then(...), создается временная ссылка. Таким образом, пока .then больше не блокируется, есть ссылка на объект, поэтому его невозможно собрать.
  • Вы правы, doMoreWork также не коллекционируется, потому что объект Promise имеет ссылку на него

Утверждение doWork().then(...) можно заменить на

new Promise(function (resolve, reject) {
  // work work work...
}).then(function doMoreWork () {
          // Some more work to do...
        })

Итак, вы можете себе представить, что вы используете объект Promise напрямую, поэтому "Верхний" -Scope - это объект, в котором используется этот объект.

Объекты обычно собираются, когда больше нет ссылок на него. Даже если код находится в Promise, это просто объект, а вызов then привязан, поэтому объект используется

Ответ 3

Чтобы узнать, является ли объект сборкой мусора, вы можете создать тест и искать утечку памяти (через диспетчер задач). Если ваш код написан правильно, все будет собрано.