akc*_*c42 20 javascript promise
我正在尝试为返回promise的对象运行测试套件.我希望将几个动作连在一起,并在它们之间进行短暂的超时.我认为返回承诺的"然后"调用将等待承诺在触发下一个链接然后调用之前完成.
我创建了一个函数
function promiseTimeout (time) {
return new Promise(function(resolve,reject){
setTimeout(function(){resolve(time);},time);
});
};
Run Code Online (Sandbox Code Playgroud)
尝试在承诺中包装setTimeout.
然后在我的测试套件中,我正在调用这样的东西......
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();
});
});
Run Code Online (Sandbox Code Playgroud)
我可以在第一个xh.fire呼叫上设置断点,在呼叫时设置第二个xu.fire呼叫,并且当从第一个断点继续到第二个断点时,预期会有两秒的间隙.
相反,它立即到达第二个断点,并且该t点的值未定义.
我究竟做错了什么?
Jar*_*a X 18
TL; DR - 您已正确地将setTimeout包装在一个承诺中,问题是您使用它是不正确的
.then(promiseTimeout(2000)).then
Run Code Online (Sandbox Code Playgroud)
不会做你期望的..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))
Run Code Online (Sandbox Code Playgroud)
vs应如何做:
Promise.resolve('hello').then(function() {
return promiseTimeout(2000)
}).then(console.log.bind(console))
Run Code Online (Sandbox Code Playgroud)
第一个输出'你好'立即
第二次输出2000秒后2秒
因此,您应该这样做:
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();
});
});
Run Code Online (Sandbox Code Playgroud)
或者:
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();
});
});
Run Code Online (Sandbox Code Playgroud)
小智 6
要使超时根据需要工作,请编写一个需要延迟的函数,然后返回适合传递给的函数then。
function timeout(ms) {
return () => new Promise(resolve => setTimeout(resolve, ms));
}
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
Promise.resolve() . then(timeout(1000)) . then(() => console.log("got here"););
Run Code Online (Sandbox Code Playgroud)
但是,您很可能希望访问导致超时的Promise的解析值。在这种情况下,请安排由创建的函数timeout()传递值:
function timeout(ms) {
return value => new Promise(resolve => setTimeout(() => resolve(value), ms));
}
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
Promise.resolve(42) . then(timeout(1000)) . then(value => console.log(value));
Run Code Online (Sandbox Code Playgroud)
上面已经回答了这个问题,但我觉得这可以通过以下方式轻松完成:
const setTimeoutPromise = ms => new Promise(resolve => setTimeout(resolve, ms))
Run Code Online (Sandbox Code Playgroud)
setTimeoutProise函数接受等待时间ms并将其传递给setTimeout函数。一旦等待时间结束,就会执行传递给 promise 的 resolve 方法。
可以这样使用:
setTimeoutPromise(3000).then(doSomething)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22320 次 |
| 最近记录: |