【问题标题】:async/promise with multiple api calls带有多个 api 调用的异步/承诺
【发布时间】:2022-01-14 02:42:59
【问题描述】:

我有点理解回调、承诺和异步等待之间的区别,但我不太确定如何将其应用于我的问题。

我删除了很多代码,但基本上我有一个运行着一个端点的应用程序,它需要执行 3 个函数(也许我需要第 4 个函数?)并且还在 3 秒内发送一个“res.end()” . 3 个功能相互依赖。我需要链接这些功能吗?我的 main() 似乎完全错误。

  • deleteRule() 必须先运行并完成
  • createRule() 必须在 deleteRule() 完成后运行
  • orderRule() 必须在 createRule() 完成后运行
router.post('/', function (req, res) {

        async function deleteRule() {
            axios.delete(DeleteURL, {auth: auth, httpsAgent: agent})
            .then(response => {
                let deleteRes = response.data
                console.log(deleteRes)
            })
        }

        const list = './jsons/list.json'

        async function createRule() {
            fs.readFile(list, 'utf-8', function(err, data) {
                if (err) throw err
                var thestuff = JSON.parse(data)
            
            axios.post(CreateURL, thestuff, {auth: auth, httpsAgent: agent})
            .then(response => {
                let createRes = response.data
                console.log(createRes)
            })
        })
        }

        async function orderRule() {
            axios.put(usOrderURL, theOrder, {auth: auth, httpsAgent: agent})
            .then(response => {
                let orderRes = response.data
                console.log(orderRes)
            })
        }

        async function main() {
            const deleteListResult = await deleteRule();
            const createListResult = await createRule();
            const orderListResult = await orderRule();
        }

        main();

        // res.end must finish in 3 seconds from the initial post on the first line
        res.end() 

    })

【问题讨论】:

  • 前三个函数声明为async,但不要使用await。那么async 就没什么用了。只需 return axios.xxxx().then() 调用返回的承诺。
  • ...或在 axios 调用上使用 await 并返回该结果。您可能还需要await main() 并进行回调async
  • 有没有办法确保 res.end() 在 3 个函数 + main() 之前完成?我现在可以正常工作了,但我要花 3 多秒才能完成所有操作。

标签: node.js async-await promise axios


【解决方案1】:

then() 调用会返回承诺,但您不会对它们做任何事情。你应该await他们,或者return他们。

由于您将函数声明为 async,因此请在其中使用 await——这就是 async 关键字的全部意义:

async function deleteRule() {
    let response = await axios.delete(DeleteURL, {auth: auth, httpsAgent: agent});
    console.log(response.data);
    return response.data;
}

对其他两个规则函数进行类似的更改。

【讨论】:

  • 我现在可以使用它,但是我的 res.end() 会在 3 秒后发送。有没有办法在其他功能仍在工作时发送 res.end()?
  • 当然有,但是查看您的代码,res.end() 会立即执行,除非您有其他代码正在等待承诺解决,但您的 main() 调用返回的承诺不是等待,所以res.end() 立即执行。
【解决方案2】:
import fs from 'fs-extra'

const list = './jsons/list.json'

async function deleteRule() {
    const response = await axios.delete(DeleteURL, {auth: auth, httpsAgent: agent})
    const deleteRes = response.data

    console.log(deleteRes)

    return deleteRes
}
async function createRule() {
    const data = await fs.readFile(list, 'utf-8')
    const theStuff = JSON.parse(data)
    const response = await axios.post(CreateURL, theStuff, {auth: auth, httpsAgent: agent})
    const createRes = response.data
    
    console.log(createRes)

    return createRes
}
async function orderRule() {
    const response = await axios.put(usOrderURL, theOrder, {auth: auth, httpsAgent: agent})
    const orderRes = response.data
    
    console.log(orderRes)

    return orderRes
}

router.post('/', async function (req, res) {
    const deleteListResult = await deleteRule();
    const createListResult = await createRule();
    const orderListResult = await orderRule();

    // res.end must finish in 3 seconds from the initial post on the first line
    res.end() 
})

【讨论】:

  • deleteRule() 运行,但后来我得到“(节点:386269)UnhandledPromiseRejectionWarning:TypeError [ERR_INVALID_CALLBACK]:回调必须是一个函数”
  • 实际上,我正在使用 fs..switched 到 fs-extra,它现在似乎正在工作。不过,res.end() 我要花 3 秒时间。
猜你喜欢
  • 1970-01-01
  • 2016-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-18
  • 2018-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多