我收到错误消息
(node:27301) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Callback was already called.
根据我的理解,在等待和拒绝Mozilla描述中拒绝承诺:
如果Promise被拒绝,则await表达式抛出被拒绝的值。
我拒绝回复中的错误,就像我的承诺一样:
Airport.nearbyAirports = async (location, cb) => {
let airports
try {
airports = await new Promise((resolve, reject) => {
Airport.find({
// code
}, (err, results) => {
if (err)
reject(err) // Reject here
else
resolve(results)
})
})
} catch (err) { // Catch here
cb(err, null)
return
}
if (!airports.empty)
cb(null, airports)
}
我的问题是
catch
语句应该保持这个错误。return
中有一个catch
语句,因此永远不应该调用它们。答案 0 :(得分:4)
问题实际上是我的框架(LoopbackJS),而不是我的功能。显然在撰写本文时,不支持使用promises:
https://loopback.io/doc/en/lb3/Using-promises.html#setup
意思是我甚至不能在我的函数中使用await
因为远程方法将我的函数包装在其他地方,所以async
总是未处理。我最终回到了内部代码的基于Promise的实现:
Airport.nearbyAirports = (location, cb) => {
const settings = Airport.dataSource.settings
const db = DB(settings)
let airports
NAME_OF_QUERY().then((res) => {
cb(null, res)
}).catch((err) => {
cb(err, null)
})
答案 1 :(得分:2)
如果Airport.find()
引发异常,则执行将跳转至catch
阻止,您的Promise
将永远不会被解决或拒绝。也许您需要将其包装在自己的try/catch
:
Airport.nearbyAirports = async (location, cb) => {
let airports
try {
airports = await new Promise((resolve, reject) => {
try {
Airport.find({
// code
}, (err, results) => {
if (err)
reject(err) // Reject here
else
resolve(results)
})
} catch (err) {
reject(err) // Reject here too
cb(err, null)
}
})
} catch (err) { // Catch here
cb(err, null)
return
}
if (!airports.empty)
cb(null, airports)
}
答案 2 :(得分:2)
作为said here,loopback 3通过允许您使用简单的返回来支持此功能。
这:
Entry.findFooById = async (id, cb) => {
const result = await Entry.findById(id);
return result;
};
......相当于:
Entry.findFooById = (id, cb) => {
Entry.findById(id)
.then(result => cb(null, result))
.catch(cb);
};
答案 3 :(得分:0)
我们使用Loopback 2.31.0,它还支持对用于远程方法的异步函数的简单返回。如果将断点放在远程方法中的某个位置,然后在调用堆栈中将其跳到上一层,您将看到如何在环回本身(shared-method.js)中实现它:
// invoke
try {
var retval = method.apply(scope, formattedArgs);
if (retval && typeof retval.then === 'function') {
return retval.then(
function(args) {
if (returns.length === 1) args = [args];
var result = SharedMethod.toResult(returns, args);
debug('- %s - promise result %j', sharedMethod.name, result);
cb(null, result);
},
cb // error handler
);
}
return retval;
} catch (err) {
debug('error caught during the invocation of %s', this.name);
return cb(err);
}
};
它在这里做什么-它调用您的函数,如果它是一个异步函数-它会返回一个诺言(retval.then === 'function'
将是true
)。在这种情况下,回信是正确的,可以正确处理您的结果。它还会为您执行错误检查,因此您不再需要尝试/捕获代码中的块了。
因此,在您自己的代码中,您只需要像下面这样使用它即可:
Airport.nearbyAirports = async (location) => {
let airports = await new Promise((resolve, reject) => {
Airport.find({
// code
}, (err, results) => {
if (err)
reject(err) // Reject here
else
resolve(results)
})
});
if (!airports.empty)
return airports;
}
else {
return {}; // not sure what you would like to return here as it wan not handled in your sample...
}
}
请注意,您完全不需要在这里使用回调(cb)。