我在nodejs中编写一个库,该图书馆正在包装另一个库。我的代码是这样的:
function wrapper(functionToWrap) {
return function(param1, param2) {
try {
return functionToWrap(param1, param2);
} catch(err) {
console.log(err);
throw err;
} finally {
finalizeWrapping();
}
}
}
问题在于我的finalizeWrapping
函数是一个函数,等待我收集的承诺(通过在其使用的某些异步API上调用函数towrap之前,请在其使用的某些异步API上放置一些挂钩(来解决,并且只有这样行动,类似的事情:<<<<<</p>
function finalizeWrapping() {
Promise.all(pendingPromises).then(function(values) {
//finalize the wrapping
console.log('all promises fulfilled!');
});
}
问题在于,在解决所有承诺并执行所有承诺之前。
我的问题是:我有什么可以解决此问题的事情,这意味着将错误置于适当的和完成当时的块,还是我必须更改挂钩的方式API是同步而不使用承诺的API?
事先感谢所有帮助者:(
编辑:试图使我的问题更清晰-functionToWrap
不是我的功能,它是另一个库的函数(并且可以更改 - 这意味着我希望我的代码能够尽可能多地包装功能(。允许此函数使用异步API(我可能要尝试进行MonkeyPatch(,并且基本上它应该具有尽可能的限制 - 我希望用户能够编写任何功能,并且我能够包装它。
不确定以下内容是否可以提供帮助,您可能没有足够的声誉来发表评论,尽管我认为您可以评论自己的问题,这是答案。
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
)
);
}