我在Express应用程序中运行了很多基于ES6 promise的代码.如果有一个从未被捕获的错误,我正在使用以下代码来处理它:
process.on('unhandledRejection', function(reason, p) {
console.log("Unhandled Rejection:", reason.stack);
process.exit(1);
});
Run Code Online (Sandbox Code Playgroud)
这适用于调试目的.
但是在生产中我想触发500错误处理程序,向用户显示标准的"出错了"页面.我有这个捕获当前适用于其他异常的所有错误处理程序:
app.use(function(error, req, res, next) {
res.status(500);
res.render('500');
});
Run Code Online (Sandbox Code Playgroud)
将unhandledRejection放在中间件中不起作用,因为它的异步和offen导致a Error: Can't render headers after they are sent to the client.
我将如何渲染500页unhandledRejection?
我有一个循环调用一个异步执行的方法.这个循环可以多次调用该方法.在这个循环之后,我有另一个循环,只有在完成所有异步操作后才需要执行.所以这说明了我的愿望:
for (i = 0; i < 5; i++) {
doSomeAsyncStuff();
}
for (i = 0; i < 5; i++) {
doSomeStuffOnlyWhenTheAsyncStuffIsFinish();
}
Run Code Online (Sandbox Code Playgroud)
我对承诺并不熟悉,所以有人能帮助我实现这一目标吗?
这是我的doSomeAsyncStuff()表现:
function doSomeAsyncStuff() {
var editor = generateCKEditor();
editor.on('instanceReady', function(evt) {
doSomeStuff();
// There should be the resolve() of the promises I think.
})
}
Run Code Online (Sandbox Code Playgroud)
也许我必须做那样的事情:
function doSomeAsyncStuff() {
var editor = generateCKEditor();
return new Promise(function(resolve,refuse) {
editor.on('instanceReady', function(evt) {
doSomeStuff();
resolve(true);
});
});
}
Run Code Online (Sandbox Code Playgroud)
但我不确定语法.
特定
let arr = [1,2,3];
function filter(num) {
return new Promise((res, rej) => {
setTimeout(() => {
if( num === 3 ) {
res(num);
} else {
rej();
}
}, 1);
});
}
function filterNums() {
return Promise.all(arr.filter(filter));
}
filterNums().then(results => {
let l = results.length;
// length should be 1, but is 3
});
Run Code Online (Sandbox Code Playgroud)
长度为3,因为返回了Promises,而不是值.有没有办法用返回Promise的函数过滤数组?
注意:对于此示例,fs.stat已替换为setTimeout,请参阅https://github.com/silenceisgolden/learn-esnext/blob/array-filter-async-function/tutorials/array-filter-with-async- function.js用于特定代码.
我读了这个问题,但很难得到承诺与打字稿一起工作.希望我们能够做出明确的指导.这适用于服务器/节点项目.我实际上正在使用最新的iojs,但将ES5作为输出.
$ tsd query es6-promise --action install --save
$ npm install --save es6-promise
// typescript code:
/// <reference path="../../typings/es6-promise/es6-promise.d.ts"/>
var Promise = require("es6-promise").Promise;
require('es6-promise').polyfill();
function test():Promise {
var p:Promise = new Promise();
return p;
}
Run Code Online (Sandbox Code Playgroud)
这是错误的:
Cannot find name 'Promise'.
Run Code Online (Sandbox Code Playgroud)
//或者:
var p = new Promise<string>((resolve, reject) => {
resolve('a string');
});
//error=> Untyped function calls may not accept type arguments.
Run Code Online (Sandbox Code Playgroud)
从您自己的节点服务器端代码返回Promise的推荐方法是什么?
引用:
如果我有一个网址数组:
var urls = ['1.txt', '2.txt', '3.txt']; // these text files contain "one", "two", "three", respectively.
Run Code Online (Sandbox Code Playgroud)
我想构建一个如下所示的对象:
var text = ['one', 'two', 'three'];
Run Code Online (Sandbox Code Playgroud)
我一直在努力学习如何做到这一点fetch,这当然会回归Promises.
有些事情我已经试过了不工作:
var promises = urls.map(url => fetch(url));
var texts = [];
Promise.all(promises)
.then(results => {
results.forEach(result => result.text()).then(t => texts.push(t))
})
Run Code Online (Sandbox Code Playgroud)
这看起来不对,无论如何它都不起作用 - 我最终没有数组['one','two','three'].
Promise.all在这里使用正确的方法?
我在我的代码中使用Express.js和Node.js v7.3.在这里我创建了一个User Router将请求转发给我的User Controller.
我在User Controller异步调用中使用async/await .问题是IntelliJ给了我一个警告说
从login()返回的Promise将被忽略.
问题是我甚至没有从login()方法中返回任何东西.
这是代码 -
UserRouter.js
router.post('/login', function (req, res, next) {
userController.login(req, res); // I get the warning here
});
Run Code Online (Sandbox Code Playgroud)
UserController.js
exports.login = async function (req, res) {
try {
const verifiedUser = await someFunction(req.body.access_code);
let user = await User.findOrCreateUser(verifiedUser);
res.status(200).send(user);
}
catch (err) {
res.status(400).send({success: false, error: err});
}
};
Run Code Online (Sandbox Code Playgroud)
如果我只使用本机承诺编写相同的登录方法,那么我不会收到此警告.我在这里理解错误或者IntelliJ有错吗?
编辑 -
感谢@Stephen,我知道async函数会返回一个promise,但如果Intellij发现没有从async函数返回任何内容并且没有显示该警告,那就不会更好了,因为当我.then()在login()函数之后链接a时,它undefined在then结果中提供一个对象.这意味着如果我们不显式地从异步函数返回一些东西,那么返回undefined?
@Domenic有一篇关于jQuery延迟对象失败的非常详尽的文章:你错过了Point of Promises.在其中,Domenic突出了jQuery承诺的一些失败,与其他包括Q,when.js,RSVP.js和ES6承诺相比.
我离开了Domenic的文章,认为jQuery承诺在概念上有一个固有的失败.我试图把这个例子放在这个概念上.
我认为jQuery实现有两个问题:
.then方法不可链接换一种说法
promise.then(a).then(b)
Run Code Online (Sandbox Code Playgroud)
jQuery将调用a随后b的时候promise满足.
由于.then在其他promise库中返回一个新的promise,它们的等价物将是:
promise.then(a)
promise.then(b)
Run Code Online (Sandbox Code Playgroud)
另一个问题似乎是异常处理,即:
try {
promise.then(a)
} catch (e) {
}
Run Code Online (Sandbox Code Playgroud)
Q中的等价物是:
try {
promise.then(a).done()
} catch (e) {
// .done() re-throws any exceptions from a
}
Run Code Online (Sandbox Code Playgroud)
在jQuery中,当acatch块失败时异常抛出并出现气泡.在其他承诺中,任何异常a将被传递到.done或.catch或其他异步捕获.如果没有任何promise API调用捕获异常,它就会消失(因此Q最佳实践,例如使用.done释放任何未处理的异常).
上述问题是否涵盖了jQuery实现承诺的问题,还是我误解或遗漏了问题?
编辑 此问题与jQuery <3.0; 从 jQuery 3.0开始,alpha jQuery是Promises/A +兼容的.
我想抓住在javascript Promise中发生的所有未处理的异常/拒绝.是否有一种很好的方法来捕获它们而不.catch(..)在Promise链的每一端添加一个?(如果忘记添加此项,则错误会无声地消失).
Google Chrome中的开发者控制台可以记录它们,我也喜欢在生产环境中记录它们.
对于普通的javascript异常,我使用该window.onerror函数,但Promise中的错误调用此函数.
例:
window.onerror = function (e) {
alert("unhandled error: " + e);
};
var p = new Promise(function (resolve, reject) {
var nullObject = null;
// Raise a TypeError: Cannot read property 'forceNullError' of null
var x = nullObject.forceNullError();
resolve();
});
p.then(function () { alert('success'); });
Run Code Online (Sandbox Code Playgroud)
JSFiddle:https://jsfiddle.net/f7zwej6L/
*)我注意到WinJS有一个.done(..)我想要的方法,但Native Promises没有.
无论我的Promise是否成功解决,我都希望运行相同的操作.我不想将同一个函数绑定到两个args .then.是不是.always像jQuery一样?如果没有,我该如何实现?
我正在尝试将Promise.allSettledAPI 与 TypeScript一起使用。代码在这里:
server.test.ts:
it('should partial success if QPS > 50', async () => {
const requests: any[] = [];
for (let i = 0; i < 51; i++) {
requests.push(rp('http://localhost:3000/place'));
}
await Promise.allSettled(requests);
// ...
});
Run Code Online (Sandbox Code Playgroud)
但是 TSC 抛出一个错误:
'PromiseConstructor'.ts(2339) 类型上不存在属性 'allSettled'
我已经将这些值添加到lib选项中tsconfig.json:
tsconfig.json:
{
"compilerOptions": {
/* Basic Options */
"target": "ES2015" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
"module": "commonjs" /* Specify …Run Code Online (Sandbox Code Playgroud) es6-promise ×10
javascript ×7
ecmascript-6 ×3
promise ×3
node.js ×2
typescript ×2
arrays ×1
async-await ×1
express ×1
fetch-api ×1
jquery ×1
q ×1