我花了太多时间试图弄清楚为什么我的express.js控制器没有响应一个简单的查询,并发现从Mongoose-promise回调中发出的运行时错误正在默默地中断回调过程.
这是我的代码的简化版本:
server.get('/api/test', function (req, res, next) {
User.find({}).exec().then(function success(users){
console.log('SUCCESS');
typo[0] = 1; // throws a runtime error
res.json(users);
}, function error(err){
console.log('ERROR');
res.json({error: err});
});
});
Run Code Online (Sandbox Code Playgroud)
这导致SUCCESS我的控制台出现,但没有任何反应.没有给用户响应,由我的拼写错误引起的错误没有出现在我的控制台中,也没有调用错误回调.
我知道不应该从回调函数中抛出异常,但在这种情况下,这只是一个错字,每当有人做这种事情时我会被警告(例如我的标准输出中的堆栈跟踪)是有意义的错误.(毕竟我们是人类......)
在您看来,在承诺回调中出现这种错误时,获得反馈的最佳方法是什么?
我对 async/await 很陌生,想知道使用 async/await 重构以下代码的最佳方法是什么?
export const createUser = (values, history) => {
return dispatch => {
axios.post('/api/signup', values)
.then(res => {
console.log('result', res);
}, rej => {
console.log('rejection', rej);
});
}
}
Run Code Online (Sandbox Code Playgroud)
当只提供一个参数时,.then对我来说非常简单,但是如果你有两个像这里这样的参数会发生什么?
所以我有一个 Express 应用程序,它使用中间件来解析 JSON POST 请求,然后填充一个req.body对象。然后我有一个承诺链,它使用 Joi 根据模式验证数据,然后将其存储在数据库中。
我想做的是检查这些进程之一之后是否抛出错误,通过发送状态代码进行适当处理,然后完全中止承诺链。我觉得应该有一些非常干净和简单的方法来做到这一点,(也许是某种中断语句?)但我在任何地方都找不到它。这是我的代码。我留下了评论,表明我希望在哪里中止承诺链。
const joi = require("joi");
const createUserSchema = joi.object().keys({
username: joi.string().alphanum().min(4).max(30).required(),
password: joi.string().alphanum().min(2).max(30).required(),
});
//Here begins my promise chain
app.post("/createUser", (req, res) => {
//validate javascript object against the createUserSchema before storing in database
createUserSchema.validate(req.body)
.catch(validationError => {
res.sendStatus(400);
//CLEANLY ABORT the promise chain here
})
.then(validatedUser => {
//accepts a hash of inputs and stores it in a database
return createUser({
username: validatedUser.username,
password: validatedUser.password
})
.catch(error => { …Run Code Online (Sandbox Code Playgroud) 我不太明白这段代码之间的区别:
co(function *() {
const val = yield aPromise();
return val;
})
.then((val) => doSomethingWith(val), (err) => doSomethingWith(err));
Run Code Online (Sandbox Code Playgroud)
还有这个:
async function () {
try {
const val = await aPromise();
doSomethingWith(val);
} catch (err) {
doSomethingWith(err);
}
}
Run Code Online (Sandbox Code Playgroud)
浏览器或服务器(node.js)中使用的每个代码的优缺点(主要在性能,可读性和流程控制方面)是什么,为什么要使用 co(取决于co 外部库)或 await(这是还不是 ES7 的一部分,取决于babel-polyfill ) 的使用。
我正在尝试处理 fetch 中的 500 个内部服务器错误。如果发生内部错误,服务器会回复一条消息。我想提取该消息。
const req = new Request(url, {
method: node.method,
mode: 'cors',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
fetch(req)
.then((response) => {
if (response.status === 500) {
// res.json extracts the body from the response as a promise, chain
// .then on it and throw an error to be caught in the lower catch.
response.json()
.then((json) => {
const { message, stackTrace } = json;
throw new ServerException(message, stackTrace); // note 1
})
.catch((error) => …Run Code Online (Sandbox Code Playgroud) 我试图从MDN文档中了解Promises .第一个例子演示了then和catch方法:
// We define what to do when the promise is resolved/fulfilled with the then() call,
// and the catch() method defines what to do if the promise is rejected.
p1.then(
// Log the fulfillment value
function(val) {
log.insertAdjacentHTML('beforeend', val +
') Promise fulfilled (<small>Async code terminated</small>)<br/>');
})
.catch(
// Log the rejection reason
function(reason) {
console.log('Handle rejected promise ('+reason+') here.');
});
Run Code Online (Sandbox Code Playgroud)
文档声明该then方法返回一个新的promise,所以不要将上面的代码等同于
var p2 = p1.then(
// Log the fulfillment …Run Code Online (Sandbox Code Playgroud) 我遇到过多个应用程序,其中使用 catch 优于拒绝处理程序。例如:偏好
new Promise.then(resolveHandler).catch()
Run Code Online (Sandbox Code Playgroud)
代替
new Promise().then(resolveHandler, rejectHandler).catch()
Run Code Online (Sandbox Code Playgroud)
这有什么特别的原因吗??
我发现
new Promise().then(resolveHandler, rejectHandler).catch()
Run Code Online (Sandbox Code Playgroud)
更有用,因为
有人知道为什么不经常使用拒绝处理程序的任何特殊原因吗?
PS 我知道 ES6 中有更新的替代品,但我只是想知道这一点。
更新:我知道 rejectHandler 和 catch 是如何工作的。问题是为什么我看到更多的人只使用 catch 而不使用 rejectHandler 和 catch?这是最佳实践还是有一些优势?
更新(在此处添加答案):找到了我正在寻找的第一手答案。原因不仅仅是因为拒绝中的错误是由 catch 处理的,主要是因为链接。当我们链接 promise.then.then.then.then 时,有一个解决方案,拒绝模式证明链接它有点棘手,因为您不想实现拒绝处理程序只是为了将拒绝数据向上转发。仅使用 promise/then/catch 和 resolve/return/throw 被证明在链接 N 个 thenable 时非常有用。@Bob-Fanger(接受的答案)也解决了部分问题。例如:
getData(id) {
return service.getData().then(dataList => {
const data = dataList.find(data => {
return data.id === id;
});
if (!data) {
// If I use Promise.reject here and use a …Run Code Online (Sandbox Code Playgroud) 我正在使用ESLint并且我收到此错误:每个then()都应该返回一个值或抛出promise/always-return
码:
return somePromise.then(result => {
console.log(result);
}).catch(error => {
console.error(error);
});
Run Code Online (Sandbox Code Playgroud)
我为什么要从这个承诺中回来?显然没有必要,因为我只想在日志中打印结果,就是这样.在所有情况下都适用这条规则似乎不对.我正在写一个Firebase数据库触发器,我相信它只对知道承诺是否已经解决感兴趣.
我有一系列的承诺,我使用catch捕获错误.
this.load()
.then(self.initialize)
.then(self.close)
.catch(function(error){
//error-handling
})
Run Code Online (Sandbox Code Playgroud)
如果链完成没有拒绝,会调用什么函数?我终于使用了,但是如果发生错误也会调用它.我想在catch函数之后调用一个函数,只有在没有承诺被拒绝的情况下才调用它.
我正在将node.js与q - 模块一起使用.
我是角度$ q服务的新手.我正在使用$http角度$q服务来实现异步请求.下面是我的代码,我无法得到后端api的结果.(JSON)
Services.js:
.service('httpService', function($q, $http, $timeout) {
var asyncRequest = function(url) {
return $http.get(url)
.then(function(response) {
//res is the index of an array in php, which will be encoded.
return response.res;
}, function(response) {
// something went wrong
return $q.reject(response.res);
});
};
return {
asyncRequest : asyncRequest
};
});
Run Code Online (Sandbox Code Playgroud)
Controller.js:
var result = httpService.test(url)
.then(function(data) {
// Line below gives me "undefined"
console.log(data);
}, function(error) {
alert("Error...!");
});
Run Code Online (Sandbox Code Playgroud)
提到的行,给我未定义.(当然,我可以在main函数中编写console.log(data),但这不是一个好习惯,因为我想将结果返回给控制器) …
我正在寻找类似的东西Promise.all,即使在一个或多个承诺拒绝或抛出错误的情况下,它也将继续同时解决承诺.每个请求都不依赖于其他请求.
接近我想要的 - 请参阅评论
function fetchRequest (request) {
return new Promise(function (resolve, reject) {
fetch(request)
.then(function(response) {
return response.text();
}).then(function (responseXML) {
//Do something here. Maybe add data to dom
resolve(responseXML);
}).catch(function (err) {
reject(new Error(err));
}
}
function promiseRequests (requests) {
var result = Promise.resolve();
for (var i = 0; i < requests.length; i++) {
result = fetchRequest(requests[i])
}
//This is wrong as it will resolve when the last promise in the requests array resolves
// - …Run Code Online (Sandbox Code Playgroud) ES2018之前,我曾经窝额外then的承诺链的末端,每当我不得不执行任何清理逻辑,我想重复,否则在then和catch更高,如
new Promise(
(res, rej) => setTimeout(() => rej({}), 1000)
).then(
res => console.log(res)
).catch(
err => console.error(err)
).then(
() => console.log('Finally')
)Run Code Online (Sandbox Code Playgroud)
但是现在finally已经在Promise原型上添加了,我看不出它then与上述方法中的最后一个有什么不同.以下将产生相同的输出.
new Promise(
(res, rej) => setTimeout(() => rej({}), 1000)
).then(
res => console.log(res)
).catch(
err => console.error(err)
).finally(
() => console.log('Finally')
)Run Code Online (Sandbox Code Playgroud)
难道finally仅仅是服务于本地无极API在语义的目的是什么?
javascript ×11
promise ×9
node.js ×7
express ×2
angularjs ×1
async-await ×1
asynchronous ×1
babeljs ×1
chaining ×1
co ×1
ecmascript-6 ×1
es6-promise ×1
eslint ×1
fetch ×1
mongoose ×1
q ×1