我在nodejs中编写一个库,即包装另一个库。我的代码是这样的:
function wrapper(functionToWrap) {
return function(param1, param2) {
try {
return functionToWrap(param1, param2);
} catch(err) {
console.log(err);
throw err;
} finally {
finalizeWrapping();
}
}
}
问题是我的finalizeWrapping
函数是一个等待我收集的promises的函数(通过在调用functionToWrap之前放置一些钩子来解决它使用的某些异步apis)来解决,然后才行动,像这样:
function finalizeWrapping() {
Promise.all(pendingPromises).then(function(values) {
//finalize the wrapping
console.log('all promises fulfilled!');
});
}
问题是在解决所有promise并执行then块之前,抛出错误并退出节点(不应处理此错误,因为包装函数不处理它)。
我的问题是:我有什么办法可以解决这个问题,这意味着错误地向用户抛出错误和完成执行then块,或者我必须改变我挂钩的方式apis是同步的而不是使用承诺?
事先感谢所有帮助者:)
编辑:尝试让我的问题更清楚 -functionToWrap
不是我的功能,它是不同库的功能(它可以改变 - 意味着我希望我的代码能够包装尽可能多的函数尽可能)。允许此函数使用异步apis(我可能尝试monkeypatch),基本上它应该具有尽可能少的限制 - 我希望用户能够编写任何函数并且我能够包装它。
答案 0 :(得分:0)
不确定以下内容是否有帮助,您可能没有足够的声誉发表评论,但我认为您可以评论自己的问题及其答案。
const wrapper = functionToWrap =>
function() {
//special type to indicate failed call to functionToWrap
const Fail = function(reason){this.reason=reason;};
//does not matter how many argument. Assuming functionToWrap
// does not rely on "this". If it does then also pass the
// object that functionToWrap is on and replace null with that object
return Promise.resolve(Array.from(arguments))
.then(
//if functionToWrap is on an object pass it to wrapper
// and replace null with that object
args=>functionToWrap.apply(null,args)
)
.catch(
//if functionToWrap throws an error or rejects we will catch it here
// and resolve with a special Fail type value
err=>{
console.log(err);
return new Fail(err)
}
).then(
//since promise cannot fail (its rejection is caught and resolves with Fail)
// this will always be called
//finalize should return Promise.all... and maybe not use a shared
// variable called pendingPromises, global shared mutable variables in async
// functions is asking for trouble
result=>finalizeWrapping().then(
()=>
//if functionToWrap rejected or thew the result will be a Fail type
(result && result.constructor === Fail)
? Promise.reject(result.reason)//reject with the original error
: result//resolve with the functionToWrap result
)
);
}