2016-04-09 2 views
2

Я пытаюсь создать объект, который будет служить постоянным состоянием моего приложения. Это означает, что при первом запуске приложения указано состояние первого времени, ему нужно загрузить объект состояния из AsyncStorage. Вот что у меня есть до сих пор:Создание состояния постоянных приложений с помощью AsyncStorage

var instance = null; 

var State = { 
    user: "bob", 

    update(newState) { 
    Object.assign(instance, newState); 
    AsyncStorage.setItem('appState', JSON.stringify(instance)).then(() => { 
     AsyncStorage.getItem('appState', (err, result) => { 
     console.log(result) 
     }) 
    }) 
    } 
} 

module.exports = (() => { 
    if (!instance) { 
    return AsyncStorage.getItem('appState').then((value) => { 
     if (value) { 
     instance = value 
     console.log("assigning saved state") 
     } else { 
     instance = State 
     console.log("assigning fresh state") 
     AsyncStorage.setItem('appState', JSON.stringify(instance)) 
     } 
     return instance 
    }) 
    } else { 
    console.log("using existing state") 
    return instance 
    } 
})(); 

Прямо сейчас, это возвращает обещание, когда я пытаюсь его использовать. Есть ли способ извлечь ценность моего объекта из обещания или лучший образец для выполнения того, что я пытаюсь сделать? Возможно, мне придется просто инициализировать State при запуске.

+0

Я бы перевел запуск на обратный вызов/обещание на хранилище, которое запускается после инициализации хранилища. Таким образом, вам не нужно разделить волосы в логике приложений. что может включать разделение кода запуска на две части: без состояния и состояния ... – dandavis

+0

Где именно вы хотите извлечь объект из обещания? Вы уже возвращаете «экземпляр». Поэтому, если вы будете следовать с помощью then(), вы получите значение экземпляра. Проблема, которую я вижу, заключается в том, что если экземпляр уже установлен, вы возвращаете его напрямую. Вы всегда должны возвращать обещание, чтобы функция была последовательной. – carlosdubusm

+0

@ dandavis: Я не уверен, что вы имеете в виду, не могли бы вы привести пример? –

ответ

1

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

constructor(props) { 
    super(props); 
    this.state = { 
     stateLoaded: false 
    } 
    State.initialize().then(() => { 
     this.setState({stateLoaded: true}) 
    }) 
    } 

    render() { 
    if (this.state.stateLoaded) { 
     return (
      // Your startup code 
    ); 
    } else { 
     return (
     // Your loading screen code 
    } 
    } 
} 

А в моем государстве класса:

initialize() { 
    if (!this.initialized) { 
     return AsyncStorage.getItem('appState').then(value=>JSON.parse(value)) 
     .then((value) => { 
     if (value) { 
      Object.assign(this, value) 
      console.log("assigning saved state") 
     } else { 
      console.log("assigning fresh state") 
      AsyncStorage.setItem('appState', JSON.stringify(this)) 
     } 
     this.intialized = true 
     return this 
     }) 
    } else { 
     return promise.resolve(this) 
    } 
    } 
} 

Теперь я могу смело ссылаться на переменные из State в течение моего приложения, так как инициализация происходит прежде всего. Насколько я знаю, это лучший (только?) Способ сделать это. Если это не так, дайте мне знать, потому что это довольно уродливо.

+0

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

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