javascript - 有条件地返回承诺或回调的包装函数
问题描述
async function wait(callback){
var awaited = await giveError();
return returner(awaited, callback)
}
function giveError(){throw new Error('oops')}
我的任务是在那里创建returner
函数,如果没有回调,它将返回一个承诺,如果确实存在则调用回调
如果returner
只返回它的第一个参数,它什么都不做,它会根据需要返回一个承诺
async function returner(awaited, callback){
console.log('triggering returner')
if(!callback){
return awaited
} else {
console.log('there is a callback')
}
}
wait().then(console.log).catch(err=>{
console.log('correct error catching here for async \n\n')
})
// prints 'correct error catching here for async'
问题是如果有回调我很难捕捉到错误(假设awaited
是一个承诺)
wait(function(err, val){
console.log('callback error handling', err, val)
})
async function returner(awaited, callback){
console.log('triggering returner')
if(!callback){
return awaited
} else {
awaited
.then(val=>{
callback(null, val)
})
.catch(err=>{
callback(err)
})
}
}
// gives UnhandledPromiseRejectionWarning: Error: oops
我有问题:
为什么“触发返回者”从不打印?
是awaited
一个承诺?如果没有,是否有可能编写returner
函数?
解决方案
为什么“触发返回者”从不打印?
因为它的await
行为就像throw
它正在等待的承诺被拒绝一样。因此代码在那里终止并且错误冒泡,return returner(..)
永远不会到达。
正在等待一个承诺?
不,它是承诺的解决值。
我实际上会编写一个函数来包装异步函数本身并接受回调:
const withCallback = fn => (...args) => {
const last = args[args.length - 1];
if(typeof last === "function") {
return fn(...args.slice(0, -1))
.then(res => last(null, res))
.catch(last);
} else {
return fn(.. args);
}
};
这样你就可以把它写成:
const wait = withCallback(async function wait(){
var awaited = await giveError();
return "result";
});
这允许您执行以下操作:
wait().then(/*...*/).catch(/*...*/)
// As well as
wait(function(error, result) { /*...*/ });
推荐阅读
- python - 如何使用 pcolor(或 imshow)绘制以每个 X、Y 散点为中心的颜色映射正方形
- ruby - 使用 Selenium webdriver 和 Ruby 在上下文菜单中导航
- java - 使用 Scanner 类时找不到行错误
- javascript - 辅助功能模块:摇树和可测试(模拟,间谍等)
- python - 如何在 catboost 分类器中将二次加权 kappa 定义为 eval_metric
- javascript - 计算两个日期之间每月的天数
- angular - 在使用 karma 和 Jasmine 进行单元测试时,Root scss 是否有可能加载到组件中
- angular - 在 Docker 中部署 Spring Boot 和 Angular 应用程序时出现 CORS 错误
- amazon-web-services - 我想从在 Windows Server 2008 SP2 上的 IIS 中运行的经典 ASP 应用程序调用 AWS Rest API
- python - contactus() 得到了一个意外的关键字参数“名称”