导入的异步函数不能正确解析数据
Imported async functions don't properly resolve data
背景:
我一直在使用 create-react-app 来创建 React 组件,我的最新项目需要 return 数据的服务器后端。
我喜欢使用从 'API' 文件中导入的函数模拟由 API 编辑的数据 return。
最近,我开始采用更新的async/await功能,主要是因为它们更易于阅读。
问题:
在我的一个组件中,我导入了这些 API 函数,我最初将它们创建为异步函数(据我了解,默认情况下,return 一个承诺并将解析值通过 return
关键字并通过 throw
关键字拒绝。
然而,当我调试代码时,我看到它调用异步函数,然后立即继续控制未定义的 "result",如果我使用 .then(res=>{console.log(res)});
它也会发生这种情况不等待promise resolve,直接进入then回调函数
**调用这些函数的代码:**
// 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;
};
修复:
问题源于尝试 return setTimeout 中的值。
await setTimeout(_=>{...},random)
不会工作,因为 setTimeout 没有 return 承诺。可以承诺一下:
const timer = ms => new Promise( res => setTimeout(res,ms));
所以你可以做到
async whatever(){
await timer(1000);
return { ... };
}
(小提示:return从超时内部调用什么都不做...)
背景:
我一直在使用 create-react-app 来创建 React 组件,我的最新项目需要 return 数据的服务器后端。
我喜欢使用从 'API' 文件中导入的函数模拟由 API 编辑的数据 return。
最近,我开始采用更新的async/await功能,主要是因为它们更易于阅读。
问题:
在我的一个组件中,我导入了这些 API 函数,我最初将它们创建为异步函数(据我了解,默认情况下,return 一个承诺并将解析值通过 return
关键字并通过 throw
关键字拒绝。
然而,当我调试代码时,我看到它调用异步函数,然后立即继续控制未定义的 "result",如果我使用 .then(res=>{console.log(res)});
它也会发生这种情况不等待promise resolve,直接进入then回调函数
**调用这些函数的代码:**
// 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;
};
修复:
问题源于尝试 return setTimeout 中的值。
await setTimeout(_=>{...},random)
不会工作,因为 setTimeout 没有 return 承诺。可以承诺一下:
const timer = ms => new Promise( res => setTimeout(res,ms));
所以你可以做到
async whatever(){
await timer(1000);
return { ... };
}
(小提示:return从超时内部调用什么都不做...)