Skip to content

Commit 6343288

Browse files
committed
Make res.render callback is always async, even for sync view engines
closes #2668
1 parent 694869d commit 6343288

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

History.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This incorporates all changes after 4.10.1 up to 4.13.1.
77
- `app.param(fn)`
88
- `req.param()` -- use `req.params`, `req.body`, or `req.query` instead
99
* change:
10+
- `res.render` callback is always async, even for sync view engines
1011
- The leading `:` character in `name` for `app.param(name, fn)` is no longer removed
1112
- Use `router` module for routing
1213
- Use `path-is-absolute` module for absolute path detection

lib/view.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,31 @@ View.prototype.lookup = function lookup(name) {
122122
*/
123123

124124
View.prototype.render = function render(options, callback) {
125+
var sync = true;
126+
125127
debug('render "%s"', this.path);
126-
this.engine(this.path, options, callback);
128+
129+
// render, normalizing sync callbacks
130+
this.engine(this.path, options, function onRender() {
131+
if (!sync) {
132+
return callback.apply(this, arguments);
133+
}
134+
135+
// copy arguments
136+
var args = new Array(arguments.length);
137+
var cntx = this;
138+
139+
for (var i = 0; i < arguments.length; i++) {
140+
args[i] = arguments[i];
141+
}
142+
143+
// force callback to be async
144+
return process.nextTick(function renderTick() {
145+
return callback.apply(cntx, args);
146+
});
147+
});
148+
149+
sync = false;
127150
};
128151

129152
/**

0 commit comments

Comments
 (0)