javascript - Set node-fetch parameter dynamically
问题描述
For a unit test I am creating a new user via POST in my database, retrieving a id and token. After that I want to DELETE this user with the id, token I just received from the first fetch.
import fetch from 'node-fetch';
type Response = {
status: number,
body: any
};
const response = {} as Response;
someFunction(async () => {
// Create new user
await fetch('http://localhost:3000/api/user/register', {
method: 'POST',
body: JSON.stringify({email: 'user@test.com', password: 'test-password'}),
headers: {'Content-Type': 'application/json'}
}).then(res => {
res.json().then(json => response.body = json);
}
);
// Delete user just created
await fetch('http://localhost:3000/api/user/' + response.body.id, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + response.body.token
}
});
});
The first fetch runs successfully response.body.id
and response.body.token
are not empty but the second fetch always fails anyways with TypeError: Cannot read property 'id' of undefined
I would appreciate if someone could point out why. Thanks
解决方案
The reason it happens is because you're mixing up some methods. When your first fetch fulfills it will call the first then()
method. Inside of that you call the json()
method of the response and chain the promise from there. Now the first then()
did not get a returned value, so the fetch
thinks it's finished. But in reality your res.json()
promise could still be running.
All the while your second fetch
request is already being called while res.json()
is still resolving. That's why the value is undefined
.
So await the first fetch and store the response. Then await the json()
promise and store the result of that. Now your thread goes through each step without having a race condition.
The values from the JSON response will now be available in your second fetch
request.
The second fetch
doesn't have to use await
. Only if you need the values from the response and need to do something whenever that request finishes.
someFunction(async () => {
// Create new user
const response = await fetch('http://localhost:3000/api/user/register', {
method: 'POST',
body: JSON.stringify({email: 'user@test.com', password: 'test-password'}),
headers: {'Content-Type': 'application/json'}
});
const json = await response.json();
// Delete user just created
fetch('http://localhost:3000/api/user/' + json.id, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + json.token
}
});
});
推荐阅读
- linux - Yocto:在我的源存储库环境中执行 shell 脚本(在下载文件夹中?)
- python - 使用字典对数据帧的索引进行分组
- spring-boot - 如何为不同的服务配置多个 OAuth2RestTemplates?
- typescript - 从数组值推断类型
- swift - 在 SwiftUI 应用程序中按下按钮时滚动到特定行的列表
- c# - 根据编辑器情况更改提交按钮的作用
- sql - Laravel -“SQLSTATE [28000] [1045] 用户'root'@'localhost'的访问被拒绝(使用密码:NO)”
- python - 从另一个系列中解析 Pandas 系列
- machine-learning - 如何解释 SVM 进行回归?
- ios - 在 UIBezierPath 中插入 CATextLayer 并旋转