[英]Imported async functions don't properly resolve data
背景:
我一直在使用create-react-app來創建React組件,我的最新項目需要服務器后端來返回數據。
我喜歡使用'API'文件中的導入函數來模擬API返回的數據。
最近,我開始采用較新的async / await函數,主要是因為它們更容易閱讀。
問題:
在我的一個組件中,我導入了這些API函數,我最初將它們創建為異步函數(據我所知,默認情況下,返回一個promise,將通過return
關鍵字解析值並通過throw
關鍵字拒絕)。
但是,當我調試代碼時,我看到它調用異步函數,然后立即繼續控制未定義的“結果”,如果我使用.then(res=>{console.log(res)});
也會發生這種情況。 .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;
};
固定:
問題源於嘗試在setTimeout中返回一個值。
await setTimeout(_=>{...},random)
不會工作因為setTimeout不會返回一個承諾。 可以宣傳它:
const timer = ms => new Promise( res => setTimeout(res,ms));
所以你可以做到
async whatever(){
await timer(1000);
return { ... };
}
(小提示:從超時內部返回什么都不做......)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.