背景:
我一直在使用create-react-app来创建React组件,而我的最新项目需要服务器后端来返回数据。
我喜欢使用来自API' API的导入函数来模拟API返回的数据。文件。
最近,我开始采用较新的async / await函数,主要是因为它们更易于阅读。
问题:
在我的一个组件中,我导入了这些API函数,我最初将它们创建为异步函数(据我所知,默认情况下,返回一个promise并将通过return
关键字解析值并拒绝通过throw
关键字)。
然而,当我调试代码时,我看到它调用异步函数,然后立即继续控制"结果"这是未定义的,如果我使用.then(res=>{console.log(res)});
它也会立即进入当时的回调函数,而不等待承诺解决。
**用于调用这些函数的代码:**
// I have removed all the other lines of code and left the important code
import { getVideoList } from './api';
runMe = async () => {
let res = await getVideolist();
console.log(res);
}
<button onClick={this.runMe}>Click Me</button>
问题在于,当使用Promises包装函数的内容并使用Promises resolve函数时,它可以正常工作。
以下是原始代码:
export let getVideoList = async () => {
let random = Math.floor(Math.random() * 3000);
setTimeout(() => {
let res = [
{
video_ID: 3,
video_url: 'https:google.com/3',
video_description: 'A basic video of exercise',
tags: ['upper-body', 'biceps', 'triceps'],
},
{
video_ID: 2,
video_url: 'https:google.com/2',
video_description: 'A basic video of exercise',
tags: ['upper-body', 'biceps', 'triceps'],
},
{
video_ID: 1,
video_url: 'https:google.com/1',
video_description: 'A basic video of exercise',
tags: ['upper-body', 'biceps', 'triceps'],
},
];
return res;
}, random);
};
export let getTags = async () => {
let random = Math.floor(Math.random() * 3000);
setTimeout(() => {
return [
{ tag_ID: 1, tagName: 'upper-body' },
{ tag_ID: 2, tagName: 'biceps' },
{ tag_ID: 3, tagName: 'triceps' },
{ tag_ID: 4, tagName: 'shoulders' },
];
}, random);
};
export let getVideos = async () => {
let random = Math.floor(Math.random() * 3000);
setTimeout(() => {
let res = [
{ video_ID: 3, video_url: 'https:google.com/3', video_description: 'A basic video of exercise' },
{ video_ID: 2, video_url: 'https:google.com/2', video_description: 'A basic video of exercise' },
{ video_ID: 1, video_url: 'https:google.com/1', video_description: 'A basic video of exercise' },
];
return res;
}, random);
};
以下是修订后的代码:
export let getVideoList = async () => {
return new Promise((res, rej) => {
let random = Math.floor(Math.random() * 3000);
setTimeout(() => {
res([
{
video_ID: 3,
video_url: 'https:google.com/3',
video_description: 'A basic video of exercise',
tags: ['upper-body', 'biceps', 'triceps'],
},
{
video_ID: 2,
video_url: 'https:google.com/2',
video_description: 'A basic video of exercise',
tags: ['upper-body', 'biceps', 'triceps'],
},
{
video_ID: 1,
video_url: 'https:google.com/1',
video_description: 'A basic video of exercise',
tags: ['upper-body', 'biceps', 'triceps'],
},
]);
return res;
}, random);
});
};
export let getTags = async () => {
return new Promise((res, rej) => {
let random = Math.floor(Math.random() * 3000);
setTimeout(() => {
res([
{ tag_ID: 1, tagName: 'upper-body' },
{ tag_ID: 2, tagName: 'biceps' },
{ tag_ID: 3, tagName: 'triceps' },
{ tag_ID: 4, tagName: 'shoulders' },
]);
}, random);
});
};
export let getVideos = async () => {
return new Promise((res, rej) => {
let random = Math.floor(Math.random() * 3000);
setTimeout(() => {
res([
{ video_ID: 3, video_url: 'https:google.com/3', video_description: 'A basic video of exercise' },
{ video_ID: 2, video_url: 'https:google.com/2', video_description: 'A basic video of exercise' },
{ video_ID: 1, video_url: 'https:google.com/1', video_description: 'A basic video of exercise' },
]);
}, random);
});
};
我不确定为什么会发生这种情况,我尝试过搜索,并且只提出了异步使用导入的新主题。
虽然这个项目在这方面不是什么大问题,但我想在未来的项目中找到底线。
修改了使用async / await的代码:
const timer = ms => new Promise(res => setTimeout(res, ms));
export let getVideoList = async () => {
let random = Math.floor(Math.random() * 3000);
await timer(random);
let res = [
{
video_ID: 3,
video_url: 'https:google.com/3',
video_description: 'A basic video of exercise',
tags: ['upper-body', 'biceps', 'triceps'],
},
{
video_ID: 2,
video_url: 'https:google.com/2',
video_description: 'A basic video of exercise',
tags: ['upper-body', 'biceps', 'triceps'],
},
{
video_ID: 1,
video_url: 'https:google.com/1',
video_description: 'A basic video of exercise',
tags: ['upper-body', 'biceps', 'triceps'],
},
];
return res;
};
export let getTags = async () => {
let random = Math.floor(Math.random() * 3000);
await timer(random);
return [
{ tag_ID: 1, tagName: 'upper-body' },
{ tag_ID: 2, tagName: 'biceps' },
{ tag_ID: 3, tagName: 'triceps' },
{ tag_ID: 4, tagName: 'shoulders' },
];
};
export let getVideos = async () => {
let random = Math.floor(Math.random() * 3000);
await timer(random);
let res = [
{ video_ID: 3, video_url: 'https:google.com/3', video_description: 'A basic video of exercise' },
{ video_ID: 2, video_url: 'https:google.com/2', video_description: 'A basic video of exercise' },
{ video_ID: 1, video_url: 'https:google.com/1', video_description: 'A basic video of exercise' },
];
return res;
};
FIX:
问题源于尝试在setTimeout中返回一个值。
答案 0 :(得分:2)
await setTimeout(_=>{...},random)
不会工作,因为setTimeout不会返回一个承诺。可以宣传它:
const timer = ms => new Promise( res => setTimeout(res,ms));
所以你可以做到
async whatever(){
await timer(1000);
return { ... };
}
(小提示:从超时内部返回什么都不做......)