我正在尝试为返回承诺的对象运行测试套件。我想将几个动作链接在一起,并且它们之间的超时很短。我认为返回承诺的“ then”调用会在启动下一个链接然后调用之前等待该承诺实现。
我创建了一个函数
function promiseTimeout (time) {
return new Promise(function(resolve,reject){
setTimeout(function(){resolve(time);},time);
});
};
尝试将setTimeout包装在Promise中。
然后在我的测试套件中,我称这样的事情...
it('should restore state when browser back button is used',function(done){
r.domOK().then(function(){
xh.fire('akc-route-change','/user/4/profile/new');
}).then(promiseTimeout(2000)).then(function(t){
xu.fire('akc-route-change','/user/6');
}).then(promiseTimeout(10)).then(function(t){
expect(xu.params[0]).to.equal(6);
history.back();
}).then(promiseTimeout(10)).then(function(){
expect(xu.params[0]).to.equal(4);
done();
});
});
我可以在第一个xh.fire
调用上放置一个断点,并在调用上放置一个第二个xu.fire
断点,当a从第一个断点继续到第二个断点时,我会期望有两秒钟的间隔。
相反,它立即到达第二个断点,并且该t
点的值是不确定的。
我究竟做错了什么?
TL; DR-您已将setTimeout正确包装在Promise中,问题是您使用它的方式不正确
.then(promiseTimeout(2000)).then
不会做你期望的。.then的“签名”是then(functionResolved, functionRejected)
promise的then方法接受两个参数:
promise.then(onFulfilled,onRejected)
onFulfilled和onRejected都是可选参数:
- 如果onFulfilled不是函数,则必须将其忽略。
- 如果onRejected不是函数,则必须将其忽略。
来源:https : //promisesaplus.com/#point-21
您没有将函数传递给
考虑您的操作方式:
Promise.resolve('hello')
.then(promiseTimeout(2000))
.then(console.log.bind(console))
与应如何做:
Promise.resolve('hello').then(function() {
return promiseTimeout(2000)
}).then(console.log.bind(console))
第一个立即输出“ hello”
第二秒2秒后输出2000
因此,您应该这样做:
it('should restore state when browser back button is used', function(done) {
r.domOK().then(function() {
xh.fire('akc-route-change', '/user/4/profile/new');
}).then(function() {
return promiseTimeout(2000);
}).then(function(t) {
xu.fire('akc-route-change', '/user/6');
}).then(function() {
return promiseTimeout(10);
}).then(function(t) {
expect(xu.params[0]).to.equal(6);
history.back();
}).then(function() {
return promiseTimeout(10);
}).then(function() {
expect(xu.params[0]).to.equal(4);
done();
});
});
或者:
it('should restore state when browser back button is used', function(done) {
r.domOK().then(function() {
xh.fire('akc-route-change', '/user/4/profile/new');
}).then(promiseTimeout.bind(null, 2000)
).then(function(t) {
xu.fire('akc-route-change', '/user/6');
}).then(promiseTimeout.bind(null, 10)
).then(function(t) {
expect(xu.params[0]).to.equal(6);
history.back();
}).then(promiseTimeout.bind(null, 10)
).then(function() {
expect(xu.params[0]).to.equal(4);
done();
});
});
多年来,情况发生了很大变化-箭头符号使操作更加容易
首先,我将以不同的方式定义promiseTimeout
const promiseTimeout = time => () => new Promise(resolve => setTimeout(resolve, time, time));
上面的代码返回一个可以调用以创建“承诺延迟”的函数,并解析为时间(延迟长度)。考虑到这一点,我看不出为什么这样做会非常有用,而是:
const promiseTimeout = time => result => new Promise(resolve => setTimeout(resolve, time, result));
以上将解决先前承诺的结果(更加有用)
但这是一个返回函数的函数,因此其余的原始代码可以保持不变。但是,关于原始代码的事情是,不需要沿.then链向下传递任何值,因此,甚至更简单
const promiseTimeout = time => () => new Promise(resolve => setTimeout(resolve, time));
并在问题的原代码it
块,现在可以使用不变
it('should restore state when browser back button is used',function(done){
r.domOK().then(function(){
xh.fire('akc-route-change','/user/4/profile/new');
}).then(promiseTimeout(2000)).then(function(){
xu.fire('akc-route-change','/user/6');
}).then(promiseTimeout(10)).then(function(){
expect(xu.params[0]).to.equal(6);
history.back();
}).then(promiseTimeout(10)).then(function(){
expect(xu.params[0]).to.equal(4);
done();
});
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句