簡體   English   中英

導入的異步功能無法正確解析數據

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM