NodeJS - return 响应作为一个进程继续工作

NodeJS - return response as a process continue working anyways

我有一个异步方法,它在一个循环中调用一些调用(等待承诺....), 最终 return 是一个结果。 当我从该函数获得结果时,我会向客户端发回响应。 我要做的是return在process/loop中间的一个响应, 而循环继续 运行ning。 当然它会打破循环,因为它 return 来自循环中间的函数。

这里有一段代码来演示。

app.post('/test', async (req, res)=>{
    const body = JSON.stringify(req.body)
    await doSomething()
    res.status(200).send("ok");
});

const doSomething = async () => {
    let times = 0;
    for(let i=0 ; i<5 ; i++){
        console.log(i)
        await delay(1000);
        if(i==2){
            return 2;
        }
    }
    return times;  
}

const delay = async (ms) => {
    return await new Promise(resolve => setTimeout(resolve, ms));
}

当我得到 i==2 时,我想 return 一个值并响应给客户端, 但我仍然希望循环到 运行 直到结束。 我想使用一些负责 return 响应的观察者, (比如 rxjs、事件发射器等...)。不确定这样的最佳做法是什么 不同的情况。

感谢任何建议。

解决方案是使用一个同步函数和return一个Promise。但是 AFAIK 将回调传递给 Promise 构造函数异步将不起作用:

const doSomething = () => {
    let times = 0;
    return new Promise(async (resolveMain) => {
        for(let i=0 ; i<5 ; i++){
            console.log(i)
            await delay(1000);
            if(i==2){
                resolveMain(2);
            }
        }
    });
}

也是变态LOL

所以我敢肯定还有很多其他方法可以做到这一点,但我假设您想保留 await delay(1000);。您需要的是一个异步生成器函数。

app.post('/test', async (req, res)=>{
    const body = JSON.stringify(req.body)
    await doSomething()
    res.status(200).send("ok");
});

async function* doLoopyThing(){
    let times = 0;
    for(let i=0 ; i<5 ; i++){
        console.log(i)
        await delay(1000);
        if(i==2){
            yield 2;
        }
    }      
}

function doSomething(){
    return new Promise(resolve => {
        const looper = doLoopyThing();
        looper.next().then(({value}) => resolve(value));
        looper.next();
    }
}

这也是扭曲的,但应该可以。

I don't understand how this can possibly be the right way to actually accomplish something. But I'm assuming the is just for fun, or you're trying to learn.

Also if all you were trying to show with the await delay(1000) was a heavy function, and you don't actually need the function to be asynchronous, the first solution should work.