refactor: add timeout in renderAndGetWindow

This commit is contained in:
Clark Du 2018-03-14 16:18:40 +08:00
parent 10cd285f57
commit 7bc3ac501b
No known key found for this signature in database
GPG Key ID: D0E5986AF78B86D9
3 changed files with 55 additions and 3 deletions

View File

@ -53,6 +53,31 @@ exports.waitFor = function waitFor(ms) {
return new Promise(resolve => setTimeout(resolve, ms || 0))
}
async function promiseFinally(fn, finalFn) {
let result
try {
if (typeof fn === 'function') {
result = await fn()
} else {
result = await fn
}
} finally {
finalFn()
}
return result
}
exports.promiseFinally = promiseFinally
exports.timeout = function timeout(fn, ms, msg) {
let timerId
const warpPromise = promiseFinally(fn, () => clearTimeout(timerId))
const timerPromise = new Promise((resolve, reject) => {
timerId = setTimeout(() => reject(new Error(msg)), ms)
})
return Promise.race([warpPromise, timerPromise])
}
exports.urlJoin = function urlJoin() {
return [].slice
.call(arguments)

View File

@ -11,7 +11,7 @@ const connect = require('connect')
const launchMiddleware = require('launch-editor-middleware')
const crypto = require('crypto')
const { setAnsiColors, isUrl, waitFor } = require('../common/utils')
const { setAnsiColors, isUrl, waitFor, timeout } = require('../common/utils')
const { Options } = require('../common')
const MetaRenderer = require('./meta')
@ -440,9 +440,9 @@ module.exports = class Renderer {
throw error
}
// Used by nuxt.js to say when the components are loaded and the app ready
await new Promise(resolve => {
await timeout(new Promise(resolve => {
window._onNuxtLoaded = () => resolve(window)
})
}), 20000, 'Components loading in renderAndGetWindow was not completed in 20s')
if (opts.virtualConsole !== false) {
// after window initialized successfully
options.virtualConsole.removeListener('jsdomError', jsdomErrHandler)

View File

@ -28,6 +28,33 @@ test('waitFor', async t => {
await Utils.waitFor()
})
test('timeout (promise)', async t => {
const result = await Utils.timeout(Promise.resolve('time not run out'), 100)
t.is(result, 'time not run out')
})
test('timeout (async function)', async t => {
const result = await Utils.timeout(async () => {
await Utils.waitFor(10)
return 'time not run out'
}, 100)
t.is(result, 'time not run out')
})
test('timeout (timeout in 100ms)', async t => {
const timeout = Utils.timeout(Utils.waitFor(200), 100, 'timeout test 100ms')
const { message } = await t.throws(timeout)
t.is(message, 'timeout test 100ms')
})
test('timeout (async timeout in 100ms)', async t => {
const timeout = Utils.timeout(async () => {
await Utils.waitFor(500)
}, 100, 'timeout test 100ms')
const { message } = await t.throws(timeout)
t.is(message, 'timeout test 100ms')
})
test('urlJoin', t => {
t.is(Utils.urlJoin('test', '/about'), 'test/about')
})