繁体   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