Node.js 为了异步调用任意函数,可以将异步函数传递给setImmediate吗?

Node.js 为了异步调用任意函数,可以将异步函数传递给setImmediate吗?,node.js,promise,Node.js,Promise,我想异步调用给定的函数。包装函数tryCallAsync是实现这一点的一种方法。这种方法有效。但是,它要求setImmediate的回调函数为异步函数。这似乎是错误的,因为回调返回的是一个未使用的承诺。为此向setImmediate传递异步函数是否错误 async function tryCallAsync(fn, ...args) { return new Promise((r, j) => { setImmediate(async () => {

我想异步调用给定的函数。包装函数tryCallAsync是实现这一点的一种方法。这种方法有效。但是,它要求setImmediate的回调函数为异步函数。这似乎是错误的,因为回调返回的是一个未使用的承诺。为此向setImmediate传递异步函数是否错误

async function tryCallAsync(fn, ...args) {

    return new Promise((r, j) => {

        setImmediate(async () => {

            try {
                r(await fn(...args));
            }
            catch (e) {
                j(e);
            }
        })
    })
}

//  Using tryCallAsync

let resolveAsync = tryCallAsync(()=>{
    return new Promise((r,j)=>{
        setImmediate(()=>r('resolveAsync'));
    });
})

resolveAsync.then((resolve)=>console.log(resolve));

let resolve = tryCallAsync(()=>{
    return 'resolve';
});

resolve.then((resolve)=>console.log(resolve));

注意:

是的,这是错误的,原因有多种:

  • setImmediate
    不处理返回的承诺,尤其是不处理错误1
  • 在使用承诺时,不要将业务逻辑放在异步(非承诺)回调中。从那里得到一个承诺,没有别的
1:即使您的特定回调从未因为
try
/
catch
而拒绝返回的承诺,它仍然感觉不正确

你的函数应该写成

async function tryCallAsync(fn, ...args) {
    await new Promise(resolve => {
        setImmediate(resolve);
    });
    return fn(...args);
}

这种方法不会浪费承诺,但是,它的性能不如传统的方法

function tryCallAsync(fn, ...args) {

    return new Promise((r, j) => {

        setImmediate(() => {

            (async function () {

                return await fn(...args);

            })().then(r).catch(j);
        });
    });
}

这是我见过的最好的方法。您写道,“在使用承诺时,不要将业务逻辑放在异步(非承诺)回调中。从那里达成承诺,其他什么都不做。”我已经读了好几遍了,我不明白您的意思。你能详细说明你的意思吗?您具体将什么称为“业务逻辑”?在基于回调的API中,您需要将异步操作完成后应运行的代码(业务逻辑)放入回调中。在基于承诺的API中,您将代码放入
.then()
回调或
等待之后。当您想要编写基于承诺的代码时,您需要并且应该在回调中只放置
if(err)reject(err)else resolve(result)
。不确定“浪费承诺”是什么意思,这种方法实际上创建了比原始方法更多的承诺:-)您可以将其简化为
返回新承诺(resolve=>{setImmediate(()=>{resolve((async()=>fn(…args));});};
@Bergi我刚才指的是我传递给setImmediate的异步函数。谢谢你分享那段代码!我对它如何处理错误感到困惑,但我想我现在看到了。这让我有很多事情要考虑:-)