2015-01-14 2 views
0

Я хочу сделать простой синглтон, используя RequireJS.Singleton in RequireJS

Что-то вроде этого:

// js/modules/singleton.js 
define([], function() { 
    var Singleton = function() { 
     this.value = 10; 
    } 
    return new Singleton(); 
}); 

В моем главном входе у меня есть следующий код:

// main.js 
    require.config({ 
      paths: { 
      singleton: 'js/modules/singleton' 
      }, 
      shim: { 

      } 
    }); 

    var o1 = require(["singleton"]); 
    var o2 = require(["singleton"]); 

console.log(o1 === o2);  // true 
console.log(o1.value);  // undefined (?!) 
console.log(o2.value);  // undefined (?!) 

o1.value = 20; 
console.log(o1.value);  // 20 
console.log(o2.value);  // 20 

o2.value = 30; 
console.log(o1.value);  // 30 
console.log(o2.value);  // 30 

переменные O1 и O2 были правильно указывая на то же одноплодной например (o1 === o2), но почему именно o1.value и o2.value undefined ??

Я бы ожидал, что атрибут «значение» будет равным 10 при этом, так как он был так инициализирован.

ответ

1

Ваша проблема в значительной степени зависит от гонки.

Простой (синхронно!) Называют как

var o1 = require(["singleton"]); 

возвращает модуль только, если он предварительно загружен с помощью асинхронной версии require().

Итак, чтобы решить вашу проблему, просто обернуть свой код в асинхронном require() вызова, как это:

require(['singleton'], function(singleton){ 

    o1 = singleton; 
    o2 = singleton; 

    console.log(o1 === o2);  // true 
    console.log(o1.value);  // 10 
    console.log(o2.value);  // 10 

    o1.value = 20; 
    console.log(o1.value);  // 20 
    console.log(o2.value);  // 20 

    o2.value = 30; 
    console.log(o1.value);  // 30 
    console.log(o2.value);  // 30 
}); 

Example Fiddle

Ссылаясь на (подсвечивание добавляемые) RequireJS documentation:

отладки консоли : Если вам нужно работать с модулем, вы уже установили , загруженный по телефону require(["module/name"], function(){}) в JavaScript консоль, то вы можете воспользоваться формой требует(), который просто использует имя строки модуля для извлечения его:

require("module/name").callSomeFunction()

Примечания это работает только, если «модуль/название» ранее было загружено через асинхронная версия запроса: require(["module/name"]). Если используется относительный путь , например, «./module/name», те, которые работают только внутри, определяют

+0

Я знаю, что могу сделать это таким образом, но в моем случае это неприемлемо. Я планирую загружать модули полностью динамически, «как раз вовремя», на основе их идентификатора (у меня много Singletones, используемых в том же модуле, и только немногие из них нужны). – Aleks

+0

Я не вижу проблемы прямо сейчас. Единственное отличие - это асинхронное кодирование и синхронизация. Для всего остального вы можете динамически создавать список зависимостей и захватывать синглтоны, используя объект 'arguments'. – Sirko

+0

Хорошо, я думаю, что у меня что-то не так ... Но если это правда, то возвращает модуль просто, если он ранее загружался с использованием асинхронной версии require() ", какова цель этого метода? – Aleks