async function wait(callback){
var awaited = await giveError();
return returner(awaited, callback)
}
function giveError(){throw new Error('oops')}
我的任务是在那里创建returner
函数,如果没有回调,它将返回一个promise,如果确实存在,则调用该回调
如果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
函数?
答案 0 :(得分:1)
为什么“触发返回者”从不打印?
因为如果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) { /*...*/ });
答案 1 :(得分:0)
async
函数将 始终 返回Promise
。如果您希望将函数的返回类型配置为根据参数而有所不同,则需要手动进行操作:
function foo(cb) {
if (typeof cb !== "function") {
return Promise.resolve("hello");
} else {
return cb("hello");
}
}
foo(v => console.log(v));
foo().then(v => console.log(v));