将同步函数包装到承诺中的最佳方式是什么

问题描述:

假设我有一个同步函数,如path.join()。我想将其包装到Promise因为我想要在catch()区块内处理优先事项。 如果我换成下面的样子,我不能在Promise.catch()区块发生异常。所以我必须使用if来检查返回值,如果它是错误的,然后调用resolve,reject函数。还有其他解决方案吗?将同步函数包装到承诺中的最佳方式是什么

var joinPaths = function(path1,path2) { 
    return new promise(function (resolve, reject) { 
    resolve(path.join(path1, path2)); 
    }); 
}; 
+2

为什么要将同步函数包装为承诺? –

+1

当需要用硬编码值替换一些异步调用时,单元测试是一种常见情况 –

+1

将同步函数包装为承诺的最佳方式不是这样做。 – Bergi

目前还不清楚为什么你会在一个承诺包的同步操作,只是使之更难以用和同步操作已经可以承诺链就好内使用。

我认为只有两个地方用它来实现某种同步的承诺非常有用,那就是启动一个承诺链,其中后续操作将是异步的,或者当您分支时,并且分支的一个结果是异步承诺,其他是同步的。然后,在这种情况下,您只需要在两种情况下都返回一个承诺,以便调用方拥有一致的异步接口,而不管采用哪个分支。

除此之外,你通常不应该使同步的东西异步,因为它只是不必要地复杂使用它们。

我知道的最简单的方法,使之变成一个承诺会是这样:

Promise.resolve(path.join(path1, path2)).then(function(path) { 
    // use the result here 
}); 

根据您的意见,一个.then()处理器中,异常已经被承诺的基础设施捕获并变成了拒绝承诺。所以,如果你有这个:

someAsyncOp().then(function(value) { 
    // some other stuff 
    // something that causes an exception 
    throw new Error("timeout"); 
}).catch(function(err){ 
    console.log(err); // will show timeout 
}); 

然后,那个例外已经映射到你的承诺拒绝。当然,如果你想处理.then()处理程序中的异常(而不是将承诺变为拒绝),那么你可以在同步操作周围使用传统的try/catch来捕获本地异常(与其他任何异常无异)同步代码)。但是,如果您希望承诺在.then()处理程序中存在异常时拒绝,那么这些都是自动完成的(这是一个非常好的承诺功能)。

+0

如果我在承诺链中使用'path.join',并且想处理''''.catch()'块中的异常,我该怎么做把它包装在承诺中? – CoderS

+2

@Srinesh - 与往常一样,如果您将实际代码和实际问题置于您的问题中,我们可以为您提供更好的帮助。我并不完全按照你所要做的。承诺链中的'.then()'处理程序已经包装在try/catch中,并且在'.then()'处理程序中抛出的任何异常都会自动拒绝承诺链。你不必为了在'.then()'处理程序中获得该功能而做任何事情。您也可以使用try/catch来捕获同步异常并在本地处理它。 – jfriend00

+1

为什么你可能想在一个promise中包装一个同步函数的一个原因是,如果你试图坚持一个契约,即'if(needsUpdating){return object.asyncUpdate(); } else {return object};'如果一个路径返回一个Promise,那么其他路径也应该如此,即使它没有运行任何异步代码。 –