简体   繁体   English

如何加快 nodejs 中的 function 调用

[英]How to speed up a function call in nodejs

I'm creating a get request to the backend as soon certain data is posted to the database.一旦某些数据发布到数据库,我就会向后端创建一个获取请求。 So in other to wait for the post request to be completed before a get request is fired, I implemented a waiting logic like so, postArray.called = true所以在其他等待发布请求完成之前获取请求被触发,我实现了一个等待逻辑, postArray.called = true

const postArray = async (arr) => {
    const movie = {
        name: searchTerm,
        result: arr
    }
    try {
        await axios({
            method: 'post',
            url: url,
            data: result,
            headers:{
                "Content-Type":"application/json",
                "Accept":"application/json"
              }
            })
    } catch (error) {
        console.log(error)
    }
    postArray.called = true
}

To make the get request wait for the post request, I used a if condition like so.为了让 get 请求等待 post 请求,我使用了这样的 if 条件。

app.get("/getNewList", (req, res)=>{
    if(postArray.called){
        process.nextTick(()=>{
            axios.get('http://localhost:3001/List')
                .then(response => res.send(response.data))
                .catch(error => res.send(error))
        })
    }
})

The problem is, this get request doesn't get call for another 2 or 3 minutes after the post request has been called.问题是,在调用发布请求后的 2 或 3 分钟内,此获取请求不会被调用。 I need a way to speed up this function call so it doesn't slow my app down completely.我需要一种方法来加快这个 function 调用,这样它就不会完全减慢我的应用程序的速度。

Sometimes, the request times out and I get a timeout error.有时,请求超时,我收到超时错误。

Is there another way to make this quicker?有没有其他方法可以让这更快?

////EDIT//// ////编辑////

I have been informed that using if(postArray.called) is not the same as making the get request wait, so I tried something else.我被告知使用if(postArray.called)与让 get 请求等待不同,所以我尝试了其他方法。

 async function getData(props){
        let Result = []
        let fetchAgain = await axios.get('/getNewList')
        Result = fetchAgain.data.find(x => x.name.toLowerCase() === props.toLowerCase()).result
        showResult(Result)
    }

 async function fetchPost(props){
      axios.post(`/${props}`)
        .then((res) =>{
            if(res.status === 200){
                getData(props)
            }
        }) 
    }

This is the new request made from the front end.这是从前端发出的新请求。 I declared a function to call the get request, then passed it to the .then part of the post request.我声明了一个 function 来调用 get 请求,然后将它传递给.then部分的 post 请求。 this still doesn't work.这仍然行不通。 Keep in mind that if(postArray.called) was removed from the get request on the backend请记住,从后端的 get 请求中删除了if(postArray.called)


The fetchPost function was used to send data to my backend which then queries two external APIs: fetchPost function 用于将数据发送到我的后端,然后查询两个外部 API:

function newFetch(a){
    const promises = [
  Fetch(`https://externalapi1?=${a}.com`,
  Fetch(`https://externalapi2?=${a}.com`,]
    
    Promise.all(promises)
        .then(values =>{
            const result = values.filter(o=>Object.values(o).every(v=>v) && Object.entries(o).length);

            postArray(result)}
        .catch(err => console.log(err))
}

This is where the postArray function is called.这是调用 postArray function 的地方。 Then I intend to fetch this data from the backend to render to my client.然后我打算从后端获取这些数据以呈现给我的客户端。 Using both failed methods listed above使用上面列出的两种失败的方法

///End EDIT/// ///结束编辑///

/////This is the place where newFetch was called//// /////这是调用newFetch的地方////

app.post("/:endpoint([\\/\\w\\ ]*)", async (req, res) =>{
    newFetchPromise = await newFetch(req.params.endpoint).catch(err => {
        newFetchPromise = null
    })
})

Assuming this is a per-server operation, not a per-user operation...假设这是每个服务器的操作,而不是每个用户的操作......

First, fix newFetch() so that it returns a promise that is tied to when postArray() is done:首先,修复newFetch()以便它返回一个 promise,它与postArray()完成时相关联:

function newFetch(a) {
    const promises = [
        Fetch(`https://externalapi1?=${a}.com`),
        Fetch(`https://externalapi2?=${a}.com`),
    ];
    return Promise.all(promises).then(values => {
        const result = values.filter(o => Object.values(o).every(v => v) && Object.entries(o).length);
        return postArray(result);
    }).catch(err => {
        // log and rethrow so caller sees the error
        console.log(err);
        throw err;
    });
}

Then, wherever you call newFetch() , you need to save the returned promise into a module-level variable:然后,无论您在哪里调用newFetch() ,都需要将返回的 promise 保存到模块级变量中:

 // module level variable
 let newFetchPromise;


 // wherever you call newFetch()
 newFetchPromise = newFetch(...).catch(err => {
     newFetchPromise = null;
 });

Then, in your route handler, you can wait for that module-level promise:然后,在您的路由处理程序中,您可以等待该模块级 promise:

app.get("/getNewList", (req, res)=>{
    if (newFetchPromise) {
        // wait for newFetchPromise
        // this will work whether newFetchPromise has already finished or is still
        // processing
        newFetchPromise.then(() => {
            return axios.get('http://localhost:3001/List');
        }).then(response => {
            res.send(response.data);
        }).catch(err => {
            // maybe want to set an error status here?
            res.send(err);
        });
    } else {
        // have to send some sort of response here if there was no newFetchPromise
        console.log("no newFetchPromise to wait for");
        res.sendStatus(500);
    }
});

As newFetch() is called again, it will just update the module-level newFetchPromise to the latest one so any new /getNewList requests will always wait for the latest promise while any prior ones will wait for the same one they originally waited for.当再次调用newFetch()时,它只会将模块级别的 newFetchPromise 更新为最新的,因此任何新的/getNewList请求将始终等待最新的 promise 而任何先前的请求将等待他们最初等待的同一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM