#javascript #react-native #callback #expo #asyncstorage
#javascript #react-native #обратный вызов #выставка #asyncstorage
Вопрос:
Я искал ответ на свою проблему, но, похоже, не могу найти ничего подобного. Мой код возвращает значение, как и ожидалось!
Я создаю приложение в React-Native и в настоящее время работаю над входом в систему. Мне нужно сохранить идентификатор пользователя, userEmail и UserToken, и я выбрал AsyncStorage и SecureStore Expo в качестве опций, но у меня действительно странная проблема, которую я никогда раньше не видел.
Я могу установить и прочитать требуемые данные, но когда я пытаюсь их использовать, это просто не работает, но когда я жестко их кодирую, это работает? (это немного сложно объяснить).
В этом и заключается проблема. Для удобства чтения я опустил остальную часть кода, он отлично работает, если я жестко закодирую приведенные ниже значения…
// Set the email and token
// Before setting these, I logged the key's values and (of course), they were null
// After setting them I logged them out again and they're set
/** from promise (no problems) **/
SecureStore.setItemAsync('shifterEmail', responseJson.email);
SecureStore.setItemAsync('shifterToken', responseJson.token);
/** returns response (no problems) **/
…тем временем, далее по странице…
/** another function **/
let shifterEmail = '';
let shifterToken = '';
SecureStore.getItemAsync('shifterEmail')
.then((email) => {
shifterEmail = email;
console.log('API email: ', shifterEmail); // my@email.com <- good!
})
.catch((error) => {
console.log('API email error: ', error);
});
SecureStore.getItemAsync('shifterToken')
.then((token) => {
shifterToken = token;
console.log('API token: ', shifterToken); // random token <- good!
})
.catch((error) => {
console.log('API token error: ', error);
});
return {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Token'
' token=' shifterToken // WHAAAT <- doesn't work
', email=' shifterEmail, // WHAAAT <- doesn't work
};
У меня была мозговая волна, и, хотя это могла быть старая добрая асинхронность, я попытался вложить их в свои обратные вызовы, но это не имеет значения.
Я показал код для SecureStore
здесь, но то же самое с AsyncStorage
, я могу получить ожидаемые значения для электронного письма и токена, но это просто не работает.
Но вот странный момент, который я не понимаю…
если я жестко закодирую токен и электронное письмо в возврате, все будет работать просто отлично!
разум = взорван
- Я могу использовать
typeof
, чтобы убедиться, что это строка. - Я пробовал
JSON.stringify()
иJSON.parse()
установить и получить. - Я попытался настроить и получить его в строке, а также в качестве вызываемых функций.
- Я попытался вложить обратные вызовы и оставить их последовательными.
- Я даже попытался добавить тайм-аут к возврату, чтобы убедиться, что все установлено.
… ничего не работает 🙁
На заметку: это обе строки, но у меня была такая же проблема с числом, и единственный способ заставить это работать — вывести ‘get’ (как из AsyncStorage, так и из SecureStore) из их вызываемых функций и вставить код в строку. Кроме того, если вместо сохранения электронного письма и токена я просто добавлю его в переменную и использую это в возврате, это работает просто отлично, но это бесполезно, поскольку пользователю придется входить в систему каждый раз, когда они открывают приложение.
Совершенно сбит с толку. Рад ответить на любые вопросы, я перепробовал множество, так что мы можем пообщаться в старом добром чате, или, если вы можете предложить другой способ входа в систему, я бы тоже хотел это услышать!
Почему я не могу использовать значение, когда оно ПРЯМО ТАМ, но могу жестко закодировать то же самое???
Спасибо!
Ответ №1:
Похоже, что это проблема с асинхронностью. На основе предоставленного вами фрагмента кода оператор return может выполняться до .then
обратного вызова.
Простым решением может быть использование async/await
или Promise.all
Например:
Асинхронный / ожидающий
const getToken = async () => {
try{
const email = await SecureStore.getItemAsync('shifterEmail')
const token = await SecureStore.getItemAsync('shifterToken')
return {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Token'
' token=' token
', email=' email
};
} catch(error) {
console.error(error);
throw error;
}
}
Promise.all
const getToken = () => {
Promise.all([
SecureStore.getItemAsync('shifterEmail'),
SecureStore.getItemAsync('shifterToken')
])
.then((response) => {
const [email, token] = response
return {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Token'
' token=' token
', email=' email
};
}
).catch((error) => {
console.error(error);
throw error;
});
}
Комментарии:
1. Спасибо за ответ, но он все тот же. Я могу выйти из системы с электронной почтой и токеном, но он не принимает их при возврате… и они выглядели такими многообещающими! (бдум тш… <- понял?! Ha!). В конце этого я попытался обернуть блок возврата в оператор IF (например,
IF(email === 'my@Email.com)
), чтобы он должен был соответствовать, прежде чем продолжить, что они и делают, но он по-прежнему не принимает электронное письмо и токен:(
Ответ №2:
Приведенный выше код выполняется асинхронно, и, как таковой, приведенный ниже код в инструкции return еще не был установлен.
Вы не опубликовали всю функцию, но оператор return, вероятно, здесь не сработает, и вам нужно будет передать функцию обратного вызова.
const doSomethingWithLogin = headers =>
console.log(headers)
Promise.all([
SecureStore.getItemAsync('shifterEmail'),
SecureStore.getItemAsync('shifterToken')
])
.then(([shifterEmail, shifterToken]) =>
Promise.resolve({
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Token'
' token=' shifterToken
', email=' shifterEmail,
})
)
.then(doSomethingWithLogin)
Комментарии:
1. Спасибо за ответ, но он все тот же. Я могу вывести электронное письмо и токен, но они не работают, когда я их использую:(
Ответ №3:
Действительно старый вопрос, но я только что столкнулся с той же проблемой и думаю, что знаю ответ.
после получения токена из хранилища при выполнении чего-то вроде:
'token=' token
что на самом деле получается: token="sadfaswerw"
Другими словами, токен по какой-то причине заключен в кавычки. Достаточно просто заменить кавычки, но немного странно.
Комментарии:
1. если я правильно помню, это было то, что обещание не использовалось, когда я его использовал, и поэтому я возвращал обещание, а не значение обещания.
2. Я вернулся к этому и понял, что проблема с моей стороны заключалась в том, что я сохранял токен как json.