edi*_*999 2 javascript timeout promise
在我的测试中,有时我会超时,这对于在超时之前查看未完成的承诺在什么地方非常有用,这样我才能知道哪些承诺最有可能处于“始终处于等待状态”。
有没有办法做到这一点 ?
这是一个示例代码:
Promise.resolve().then(function firstFunction() {
console.log(1);
return 1;
}).then(function () {
return new Promise(function secondFunction(resolve, reject) {
// NEVER RESOLVING PROMISE
console.log(2);
});
}).then(function thirdFunction() {
// function that will never be called
console.log(3);
})
setTimeout(function timeoutTest() {
const pendingPromises = [];// ??????????? how do I get the pendingPromises
console.log(pendingPromises);
process.exit();
}, 5000);
Run Code Online (Sandbox Code Playgroud)
如果可能的话,我想获得pendingPromises函数的名称和promise的stacktrace secondFunction,因为它是永远无法解决的。
一个promise链被逐步设计为在其成功路径下传递值,或在其错误路径下传递“原因”。它并非旨在在某个任意时间询问“快照”所吸收的单个承诺的状态。
因此,承诺链不会提供“自然”的方式来完成您要问的事情。
您需要设计一种机制:
遵循这些原则的构造函数将完成这项工作:
function Inspector() {
var arr = [];
this.add = function(p, label) {
p.label = label || '';
if(!p.state) {
p.state = 'pending';
p.then(
function(val) { p.state = 'resolved'; },
function(e) { p.state = 'rejected'; }
);
}
arr.push(p);
return p;
};
this.getPending = function() {
return arr.filter(function(p) { return p.state === 'pending'; });
};
this.getSettled = function() {
return arr.filter(function(p) { return p.state !== 'pending'; });
};
this.getResolved = function() {
return arr.filter(function(p) { return p.state === 'resolved'; });
};
this.getRejected = function() {
return arr.filter(function(p) { return p.state === 'rejected'; });
};
this.getAll = function() {
return arr.slice(0); // return a copy of arr, not arr itself.
};
};
Run Code Online (Sandbox Code Playgroud)
问题所需的唯一方法是.add()和.getPending()。提供其他内容是为了完整性。
您现在可以写:
var inspector = new Inspector();
Promise.resolve().then(function() {
console.log(1);
}).then(function() {
var p = new Promise(function(resolve, reject) {
// NEVER RESOLVING PROMISE
console.log(2);
});
return inspector.add(p, '2');
}).then(function() {
// function that will never be called
console.log(3);
});
setTimeout(function() {
const pendingPromises = inspector.getPending();
console.log(pendingPromises);
process.exit();
}, 5000);
Run Code Online (Sandbox Code Playgroud)
的使用Inspector不限于承诺链所吸收的承诺。它可以用于任何任意的Promise承诺,例如要与之集合的集合Promise.all():
promise_1 = ...;
promise_2 = ...;
promise_3 = ...;
var inspector = new Inspector();
inspector.add(promise_1, 'promise 1');
inspector.add(promise_2, 'promise 2');
inspector.add(promise_3, 'promise 3');
var start = Date.now();
var intervalRef = setInterval(function() {
console.log(Date.now() - start + ': ' + inspector.getSettled().length + ' of ' + inspector.getAll().length + ' promises have settled');
}, 50);
Promise.all(inspector.getAll()).then(successHandler).catch(errorHandler).finally(function() {
clearInterval(intervalRef);
});
Run Code Online (Sandbox Code Playgroud)