Javascript 计算承诺到拒绝的总时间?
我想测试我能做多少请求,并得到它们的总时间。我的Javascript 计算承诺到拒绝的总时间?,javascript,node.js,promise,Javascript,Node.js,Promise,我想测试我能做多少请求,并得到它们的总时间。我的承诺功能 async execQuery(response, query) { let request = new SQL.Request(); return new Promise((resolve, reject) => { request.query(query, (error, result) => { if (error) { rejec
承诺
功能
async execQuery(response, query) {
let request = new SQL.Request();
return new Promise((resolve, reject) => {
request.query(query, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
和我的api
app.get('/api/bookings/:uid', (req, res) => {
let st = new stopwatch();
let id = req.params.uid;
let query = `SELECT * FROM booking.TransactionDetails WHERE UID='${id}'`;
for (let i = 0; i < 10000; i++) {
st.start();
db.execQuery(res, query);
}
});
app.get('/api/bookings/:uid',(req,res)=>{
让st=新秒表();
设id=req.params.uid;
让query=`SELECT*FROM booking.TransactionDetails,其中UID='${id}`;
for(设i=0;i<10000;i++){
st.start();
db.execQuery(res,query);
}
});
我无法停止
for
循环,因为它是异步的
,但我也不知道如何在第一次拒绝后停止执行其他调用,以便获得计数器和所有成功承诺的运行时间。我怎样才能做到这一点呢?这不符合你的承诺吗
new Promise((resolve, reject) => {
var time = Date.now();
request.query(query, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
}).then(function(r){
//code
}).catch(function(e){
console.log('it took : ', Date.now() - time);
});
或者将.then和.catch放在db.execQuery()调用之后您可以轻松地为此创建一个可组合的包装器,或者创建一个子类: 继承: 然后您可以使用以下方法:
TimedPromise.all(promises);
TimedPromise.race(promises);
var foo = new TimedPromise(resolve => setTimeout(resolve, 100);
let res = await foo;
console.log(foo.time); // how long foo took
再加上链接将起作用,异步函数将不起作用(因为它们总是返回本机承诺)
组成:
那么用法是:
var foo = new Promise(resolve => setTimeout(resolve, 100);
var timed = time(foo);
await foo;
console.log(timed()); // how long foo took
这样做的优点是可以在任何地方工作,但缺点是必须手动计算每个承诺的时间。我更喜欢这种方法,因为它的明确性和可以说更好的设计
作为警告,由于附加了拒绝处理程序,你必须100%确定你正在添加你自己的。catch
或然后处理程序,否则错误将不会记录到控制台。你做了两条评论,当承诺失败但没有提到什么是SQL
,如果request.query
可以取消
在for循环中,您已经运行了所有的request.query
语句,如果您只想运行一个查询,然后再运行另一个查询,则必须执行request.query(query)。然后(=>request.query(query))。然后…
,但这将花费更长的时间,因为您不会一次启动所有查询
下面的代码可以告诉您所有查询花费了多长时间,但我认为您应该告诉我们什么是SQL
,这样我们就可以知道如何设置连接池和缓存(可能是最大的性能增益)
//删除了异步,此函数不等待任何操作
//因此,不需要异步
//已删除初始化请求,您可以重新使用在中创建的请求
//run函数,它可以节省总运行时的一些时间
//但不确定请求是否可以共享连接(在这种情况下)
//最好创建一对夫妇,并将其作为他们的
//连接可用(连接池)
const execQuery=(响应、查询、请求)=>
新承诺(
(解决、拒绝)=>
request.query(
查询
,(错误、结果)=>
(错误)
?拒绝(错误)
:解析(结果)
)
);
//保存失败的查询并使用Fail对象解决它们
const Fail=function(detail){this.detail=detail;};
//let request=new SQL.request();
const run=(numberOfTimes)=>{
const start=new Date().getTime();
const request=new SQL.request();
我保证(
(x=>{
for(设i=0;i[x,查询]
,err=>[err,query]
)
}
})()//iLife创建承诺数组
)
.那么(
结果=>{
const totalRuntime=new Date().getTime()-start;
const failed=results.filter(r=>(r&r.constructor)==Fail);
log(`Total runtime in ms:${totalRuntime}
失败:${Failed.length}
成功:${results.length失败。length}`);
}
)
};
//从以下几点开始:
运行(10000);
您不希望这样构建SQL。开始使用参数化查询。@Tomalak我知道,它会被更改,但我想先实现这一点。但是,当您想测量您可以执行的请求数量时,您需要使用生产中使用的相同方法。测量你不打算使用的东西有什么意义?更重要的是,衡量您可以运行完全相同的查询的频率有什么意义?我想强调一下服务器并获得所有成功的请求,直到超时。当它异步拒绝承诺时,您的所有查询都已经开始了。你不能“阻止”他们。或者,request
是否有一个stop()
方法或其他什么?问题是,它一直在执行其他承诺,而这些承诺在第一次拒绝之后等待。当我第一次被拒绝时,我想阻止所有其他人。如果您的承诺的状态取决于此承诺的成功与否,为什么不在then()函数中调用它们(而不是//code
)?
function time(promise) {
var startTime = performance.now(), endTime;
let end = () => endTime = performance.now();
promise.then(end, end); // replace with finally when appropriate.
return () => startTime - endTime;
}
var foo = new Promise(resolve => setTimeout(resolve, 100);
var timed = time(foo);
await foo;
console.log(timed()); // how long foo took
//removed the async, this function does not await anything
// so there is no need for async
//removed initializing request, you can re use the one created in
// the run function, that may shave some time off total runtime
// but not sure if request can share connections (in that case)
// it's better to create a couple and pass them along as their
// connection becomes available (connection pooling)
const execQuery = (response, query, request) =>
new Promise(
(resolve, reject) =>
request.query(
query
,(error, result) =>
(error)
? reject(error)
: resolve(result)
)
);
// save failed queries and resolve them with Fail object
const Fail = function(detail){this.detail=detail;};
// let request = new SQL.Request();
const run = (numberOfTimes) => {
const start = new Date().getTime();
const request = new SQL.Request();
Promise.all(
(x=>{
for (let i = 0; i < numberOfTimes; i++) {
let query = `SELECT * FROM booking.TransactionDetails WHERE UID='${i}'`;
db.execQuery(res, query, request)
.then(
x=>[x,query]
,err=>[err,query]
)
}
})()//IIFE creating array of promises
)
.then(
results => {
const totalRuntime = new Date().getTime()-start;
const failed = results.filter(r=>(r&&r.constructor)===Fail);
console.log(`Total runtime in ms:${totalRuntime}
Failed:${failed.length}
Succeeded:${results.length-failed.length}`);
}
)
};
//start the whole thing with:
run(10000);