将同步函数包装到promise中的最佳方法是什么

s1n*_*7ax 8 javascript node.js promise

假设我有一个同步功能path.join().我想把它包装成一个Promise因为我希望在catch()块内处理异常.如果我包裹像下面,我不能在异常Promise.catch()块.所以我必须用来if检查返回值,如果它是一个错误,然后调用resolve,拒绝函数.还有其他解决方案吗?

var joinPaths = function(path1,path2) {
  return new promise(function (resolve, reject) {
    resolve(path.join(path1, path2));
  });
};
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 12

目前还不清楚为什么要将一个同步操作包装在一个promise中,因为它使得它更难以使用,同步操作已经可以在promise链中使用了.

我认为只有两个地方对同步事物做出承诺很有用,就是启动一个承诺链,后续操作将是异步的,或者当你进行分支时,分支的一个结果是异步承诺而另一个是同步的.然后,在这种情况下,您希望在两种情况下都只返回一个promise,这样无论采用哪个分支,调用者都具有一致的异步接口.

除此之外,通常不应该使同步事物异步,因为它只是不必要地使用它们变得复杂.

我所知道的最简单的方法是将其变成一个承诺:

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

根据您的评论,在.then()处理程序中,promise基础结构已捕获异常,并将其转换为拒绝的承诺.所以,如果你有这个:

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
});
Run Code Online (Sandbox Code Playgroud)

然后,该异常已经映射到您的承诺拒绝.当然,如果你想处理处理.then()程序内部的异常(不将promise转为拒绝),那么你可以在同步操作中使用传统的try/catch来捕获本地异常(与任何其他同步没有什么不同)码).但是,如果您希望承诺拒绝.then()处理程序内部存在异常,那么这一切都是自动完成的(承诺的一个非常好的功能).

  • 您可能希望在承诺中包含同步函数的一个原因是,如果您试图坚持合同,即`if(needsUpdating){return object.asyncUpdate(); } else {return object};`如果一个路径返回一个Promise,那么另一个路径也是如此,即使它没有运行任何异步代码. (4认同)
  • @Srinesh - 与往常一样,如果您将实际代码和实际问题放入您的问题中,我们可以更好地帮助您.我并不完全遵循你想要做的事情.promise链中的`.then()`处理程序已经包含在try/catch中,并且`.then()`处理程序中抛出的任何异常都会自动拒绝promise链.您无需在`.then()`处理程序中执行任何操作即可获得该功能.您也可以自己使用try/catch来捕获同步异常并在本地处理它. (2认同)

Tha*_*ish 7

不确定这是否是最好的方法,但它有效。我来到 StackOverflow 是为了检查是否有更好的方法。

new Promise((resolve, reject) => {
    try {
        resolve(path.join());
    } catch (err) {
        reject(err);
    }
})
Run Code Online (Sandbox Code Playgroud)