在我的ReactNative
应用程序中,我试图想出一个很好的模式来读取我存储在AsyncStorage
中的access_token
并在fetch
调用中使用它。
换句话说,我想创建一个使用某种类型的包装器的模式,以确保fetch
调用始终具有所需的access_token
。所以执行顺序应该始终是:
调用获取调用 -> 从异步存储获取令牌和准备标头 ->执行获取调用
我想出了以下代码,但看起来我在AsyncStorage
的Async
部分遇到了问题,我的fetch
调用在没有令牌的情况下发出。
这是我fetch
电话:
export const someApiCall = (request) => {
const url = 'https://myapi.com/add';
return (dispatch) => fetch(url, fetchOptionsPost(request))
.then((response) => {
if (response.ok && response.status === 200) {
// Got data. Dispatch some action
}
})
}
在这里,我使用辅助函数来准备标头等。以下是fetchOptionsPost()
的外观:
export const fetchOptionsPost = (request) => {
getAccessToken()
.then(token => {
return {
method: 'POST',
mode: 'cors',
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
},
body: JSON.stringify(request)
}
});
};
getAccessToken()
函数只是从AsyncStorage
中读取它,如下所示:
export const getAccessToken = async () => {
return await AsyncStorage.getItem("access_token");
}
此模式不起作用,API 调用在没有令牌的情况下发出。
我还想提一下,如果我在fetchOptionsPost()
方法中对令牌进行硬编码,一切正常。显然,这里的问题是fetchOptionsPost()
没有返回任何内容。
我该怎么做才能确保我的代币始终在我的fetchOptionsPost
中?
您可以在函数中添加token
调用someApiCall
。并在函数内部创建选项。函数是异步的,因此仅在获取令牌结果后运行
更新
const fetchOptionsPost = (token) =>{
return ({
method: 'POST',
mode: 'cors',
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
}
})
}
export const someApiCall = async(request) => {
const token = await AsyncStorage.getItem("access_token");
const url = 'https://myapi.com/add';
fetch(url, fetchOptionsPost(token))
.then(response=>response.json())
.then((data)=>{
// call the dispatch here
})
}
为什么在主函数内部使用异步
AsyncStorage
只有异步回调。 如果将 AsyncStorage 设置为单独的函数,则应为这两个函数调用 Async。这就是为什么我在父异步函数中添加并将令牌传递给fetchOptionsPost
这是我提出的似乎工作正常的方法。我仍然希望对此代码有任何建议或改进。
首先,这是我fetch
呼叫现在的样子。我把它包装在getAccessToken()
函数中,这是一个async
调用,但因为我正在使用redux-thunk
,所以我能够做到这一点。
export const someApiCall = (request) => {
const url = 'https://myapi.com/add';
return (dispatch) => getAccessToken()
.then(token => {
fetch(url, fetchOptionsPost(request, token))
.then((response) => {
if (response.ok && response.status === 200) {
// Got data. Dispatch some action
}
})
})
}
我稍微更改了我的fetchOptionsPost()
帮助程序函数,该函数现在接受令牌。它现在也更强大了。如果它没有获得令牌,则只需省略标头中的Authorization
部分。我选择了这种方法,因为对我的 API 后端的某些调用不需要身份验证。此外,isValidString()
是我创建的另一个帮助程序验证函数,以确保我确实获得了有效的字符串。它根据输入的字符串值返回TRUE
或FALSE
响应:
export const fetchOptionsPost = (data, token = null) => {
if (isValidString(token)) {
return {
method: 'POST',
mode: 'cors',
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
},
body: JSON.stringify(data)
}
} else {
return {
method: 'POST',
mode: 'cors',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
}
}
};
最后,getAccessToken()
函数并没有真正改变,但这里是:
export const getAccessToken = async () => {
return await AsyncStorage.getItem("access_token");
}
正如我所说,我将不胜感激任何关于进一步改进此代码的意见或建议。
希望这对其他人有用。
使用异步和等待方法,并在每次调用之前获取令牌。
async ()=>{
let token =await getTokenFromLocal();
return (dispatch) => fetch(url, fetchOptionsPost(request))
.then((response) => {
if (response.ok && response.status === 200) {
// Got data. Dispatch some action
}
})
}