在履行承诺之前检查 url 状态
checking on url status before fulfilling a promise
我有一个 cypress 测试运行器的非典型用例,我需要从 cypress 中启动服务器。
我通过在 cypress plugins/index.js
中定义 before:spec
钩子来做到这一点,就像这样:
module.exports = (on, config) => {
on('before:spec', async(spec) => {
// the promise will be awaited before the runner continues with the spec
return new Promise((resolve, reject) => {
startServer();
// keep checking that the url accessible, when it is: resolve(null)
while (true) {
getStatus(function(statusCode) {
if (statusCode === 200)
break
})
};
resolve(null)
我正在努力实现这个 while 循环,它应该在履行 before:spec
承诺之前继续检查 url 是否可访问。
我有以下功能来检查 url:
function getStatus (callback) {
const options = {
hostname: 'localhost',
port: 8080,
path: '/',
method: 'GET'
}
const req = http.request(options, res => {
console.log(`statusCode: ${res.statusCode}`)
callback(res.statusCode}
})
req.on('error', error => {
console.error("ERROR",error)
})
req.end()
};
任何帮助实施该循环或其他建议如何在履行 before:spec
承诺之前完成检查 url 的任务表示赞赏。
理想情况下,您的 startServer
函数应该 return 一个 promise,并且在 before:spec
中简单地钩住您 await startServer();
。或者至少应该接受在服务器初始化完成时调用的回调。但是让我们假设这是不可能的,所以这是给定代码的另一种解决方案:
function getStatus() {
return new Promise((resolve, reject) => {
const options = {
hostname: 'localhost',
port: 8080,
path: '/',
method: 'GET'
}
const req = http.request(options, res => {
console.log(`statusCode: ${res.statusCode}`)
resolve(res.statusCode);
})
req.on('error', error => {
console.error("ERROR", error);
reject(error);
})
req.end()
});
};
module.exports = (on, config) => {
on('before:spec', async (spec) => {
// the promise will be awaited before the runner continues with the spec
startServer();
// keep checking that the url accessible, when it is: resolve(null)
while (await getStatus() !== 200) {
await (new Promise(resolve => setTimeout(resolve, 50)));
}
});
}
你最初的 while 循环尝试有严重的缺陷,因为你不能那样中断,你的服务器充满了请求。
目前只有一处奇怪,await (new Promise(resolve => setTimeout(resolve, 50)));
。这只是为了防止泛洪,如果服务尚未准备好,让我们给 50 毫秒。如果您知道您的服务启动速度确实较慢,请随意调整它,但更低的值没有多大意义。实际上它甚至不是绝对必要的,因为 while 循环中的条件确保一次只有一个请求 运行 。但我觉得这样更安全一些,如果它还在热身,那么频繁地尝试服务器是没有意义的。
另请注意,您可能希望在 req.on('error') 中 resolve(500)
或省略 resolve/reject,因为我不知道您的服务器是否立即准备就绪return 正确的状态代码,这取决于 startServer
.
的实现
我有一个 cypress 测试运行器的非典型用例,我需要从 cypress 中启动服务器。
我通过在 cypress plugins/index.js
中定义 before:spec
钩子来做到这一点,就像这样:
module.exports = (on, config) => {
on('before:spec', async(spec) => {
// the promise will be awaited before the runner continues with the spec
return new Promise((resolve, reject) => {
startServer();
// keep checking that the url accessible, when it is: resolve(null)
while (true) {
getStatus(function(statusCode) {
if (statusCode === 200)
break
})
};
resolve(null)
我正在努力实现这个 while 循环,它应该在履行 before:spec
承诺之前继续检查 url 是否可访问。
我有以下功能来检查 url:
function getStatus (callback) {
const options = {
hostname: 'localhost',
port: 8080,
path: '/',
method: 'GET'
}
const req = http.request(options, res => {
console.log(`statusCode: ${res.statusCode}`)
callback(res.statusCode}
})
req.on('error', error => {
console.error("ERROR",error)
})
req.end()
};
任何帮助实施该循环或其他建议如何在履行 before:spec
承诺之前完成检查 url 的任务表示赞赏。
理想情况下,您的 startServer
函数应该 return 一个 promise,并且在 before:spec
中简单地钩住您 await startServer();
。或者至少应该接受在服务器初始化完成时调用的回调。但是让我们假设这是不可能的,所以这是给定代码的另一种解决方案:
function getStatus() {
return new Promise((resolve, reject) => {
const options = {
hostname: 'localhost',
port: 8080,
path: '/',
method: 'GET'
}
const req = http.request(options, res => {
console.log(`statusCode: ${res.statusCode}`)
resolve(res.statusCode);
})
req.on('error', error => {
console.error("ERROR", error);
reject(error);
})
req.end()
});
};
module.exports = (on, config) => {
on('before:spec', async (spec) => {
// the promise will be awaited before the runner continues with the spec
startServer();
// keep checking that the url accessible, when it is: resolve(null)
while (await getStatus() !== 200) {
await (new Promise(resolve => setTimeout(resolve, 50)));
}
});
}
你最初的 while 循环尝试有严重的缺陷,因为你不能那样中断,你的服务器充满了请求。
目前只有一处奇怪,await (new Promise(resolve => setTimeout(resolve, 50)));
。这只是为了防止泛洪,如果服务尚未准备好,让我们给 50 毫秒。如果您知道您的服务启动速度确实较慢,请随意调整它,但更低的值没有多大意义。实际上它甚至不是绝对必要的,因为 while 循环中的条件确保一次只有一个请求 运行 。但我觉得这样更安全一些,如果它还在热身,那么频繁地尝试服务器是没有意义的。
另请注意,您可能希望在 req.on('error') 中 resolve(500)
或省略 resolve/reject,因为我不知道您的服务器是否立即准备就绪return 正确的状态代码,这取决于 startServer
.