问题描述
对于单元测试,我要通过POST在数据库中创建一个新用户,并检索ID和令牌。之后,我想删除该用户的ID,即我从第一次提取中获得的令牌。
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: '[email protected]',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
}
});
});
第一次获取成功运行response.body.id
并且response.body.token
不为空,但是无论如何,第二次获取总是失败,TypeError: Cannot read property 'id' of undefined
如果有人能指出原因,我将不胜感激。谢谢
解决方法
发生这种情况的原因是因为您混淆了一些方法。当您的第一个提取完成时,它将调用第一个then()
方法。在其中,您调用响应的json()
方法,并从那里链接promise。现在,第一个then()
未获得返回值,因此fetch
认为已完成。但实际上,您的res.json()
承诺仍然可以兑现。
在fetch
仍在解析的同时,您的第二个res.json()
请求已被调用。这就是为什么值是undefined
。
因此,等待第一次获取并存储响应。然后等待json()
承诺并存储其结果。现在,您的线程在没有竞争条件的情况下经历了每个步骤。
来自JSON响应的值现在将在您的第二个fetch
请求中可用。
第二个fetch
不必使用await
。仅当您需要响应中的值并且在请求完成时需要执行某些操作时。
someFunction(async () => {
// Create new user
const response = await fetch('http://localhost:3000/api/user/register',{
method: 'POST',body: JSON.stringify({email: '[email protected]',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
}
});
});