异步长时间运行的API调用

时间:2020-09-16 23:09:18

标签: python reactjs django async-await

我的react应用程序中有一个将数据发送到Django API的函数。收到该数据后,django会调用一个外部python函数来执行一些代码。

当前,我让javascript在收到ok响应时给我警报。但是,在外部功能完成之前,Django不会发送此响应。这是一个问题,因为根据用户的输入,外部功能最多可能需要一个小时才能运行。可以将其更改为在外部python代码开始成功运行后发出警报,而在功能完成后再次发出警报吗?

我了解到,当将数据发送到API时,它们可能会失败,API可能无法访问数据,可能是由于数据类型不匹配,最后是如果数据与外部功能不兼容。我正在从异步函数中寻找3种不同的响应 反应

export const SendData = (url, props) =>{ //this url is the url to the DataInput api view
    const data1 = document.getElementById('data1')
    const data2 = document.getElementById('data2')

    async function postData() {
        var res = ''
        const options ={
            method : 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json;charset=UTF-8'
            },
            body: JSON.stringify({
            data_one: data1,
            data_two: data2
            })
        }
        const response = await fetch(url, options)
            .then(response => {
                if (response.ok) {
                    alert("Data Sent!")
                }
                else {
                    alert("An error has occurred.\nWere all fields filled out?")
                }
            });
    }       
    postData()
};

models.py

class DataInput(models.Model):
    data_one = models.IntegerField(
        max_length=30,
        default=5)
    data_two = models.IntegerField(
        max_length=30,
        default=4)

class OtherData(models.Model):
    other_data = models.IntegerField(
        max_length=5,
        default=10)

@receiver(post_save, sender=DataInput, dispatch_uid="extra function")
def extra_function(sender, instance, created, *args, **kwargs):
    #dummy function to show reliance on data
    for i in OtherData[0].other_data:
        print(instance.data_two + instance.data_one)

serializer.py

from rest_framework import serializers
from .models import DataInput
from .models import OtherData
class DataSerializer(serilizers.ModelSerializer):
    class Meta:
        model = DataInput
        fields = ('data_one', 'data_two')
class OtherDataSerializer(serializer.ModelSerializer):
    class Meta:
        model = OtherData
        fields = ('other_data')

1 个答案:

答案 0 :(得分:1)

最好避免在同一(http)连接中为长时间运行的操作同步等待响应。尤其是在浏览器中,因为它们可能会导致超时(取决于浏览器,但取决于usually 1-5 minutes

使用HTTP轮询的解决方案之一。可以在这里找到有关此技术的很好的解释:

正如您在第二个链接中发现的那样,您的API应该在开始长期运行的过程之前验证请求和要执行的操作。如果请求无效,请立即使用诸如HTTP 400(错误请求)的错误代码进行回复。在其他情况下,将任务交给后台工作人员(例如 django-q),其响应的位置可以使响应应用程序轮询等待的工作结果。