您如何将setTimeout包装在Promise中

akc42

我正在尝试为返回承诺的对象运行测试套件。我想将几个动作链接在一起,并且它们之间的超时很短。我认为返回承诺的“ 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的值是不确定的。

我究竟做错了什么?

Jaromanda X

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();
    });
});

编辑:2019年3月

多年来,情况发生了很大变化-箭头符号使操作更加容易

首先,我将以不同的方式定义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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何将cordova getAppVersion包装在可变promise上?

来自分类Dev

如何将DropDownList包装在GridView FooterTemplate中?

来自分类Dev

如何将图像包装在winforms listview中?

来自分类Dev

如何将Ajax权限检查包装在函数中?

来自分类Dev

如何将HTML元素包装在框中?

来自分类Dev

如何将<a>元素包装在表中?

来自分类Dev

如何将jQuery内容包装在H标签中?

来自分类Dev

如何将列表项包装在link_to中?

来自分类Dev

如何将UILabel包装在原型单元中

来自分类Dev

如何将python模块包装在tar中?

来自分类Dev

如何将子元素包装在父标签中?

来自分类Dev

如何将 div 包装在新的 div 中?

来自分类Dev

如何将类包装在高阶组件中?

来自分类Dev

将异步功能包装在Promise中

来自分类Dev

如何将常量放入 React 组件中,包装在 recompose 中

来自分类Dev

这是将readFileSync包装在Promise中的正确方法吗

来自分类Dev

如何将长代码行包装在google-code-prettify中

来自分类Dev

斯威夫特:如何将异步方法包装在同步方法中?

来自分类Dev

HAML遍历集合-如何将子元素组包装在唯一的父级中?

来自分类Dev

如何将每个Express JS请求包装在域或trycatch中

来自分类Dev

如何将img宽度的百分比包装在特定的div宽度中?

来自分类Dev

Flutter:如何将数学方程式包装在容器中?

来自分类Dev

如何将Flex Cloumns包装在移动设备的单行中

来自分类Dev

如何将长代码行包装在google-code-prettify中

来自分类Dev

如何将WCF客户端包装在共享库中

来自分类Dev

如何将jQuery Justified Gallery包装在Ember组件中?

来自分类Dev

如何将参数传递给JS函数而不将其包装在匿名函数中?

来自分类Dev

如何将这组li元素包装在ul容器中?

来自分类Dev

如何将现有的iOS代码包装在新的Appcelerator模块中?

Related 相关文章

  1. 1

    如何将cordova getAppVersion包装在可变promise上?

  2. 2

    如何将DropDownList包装在GridView FooterTemplate中?

  3. 3

    如何将图像包装在winforms listview中?

  4. 4

    如何将Ajax权限检查包装在函数中?

  5. 5

    如何将HTML元素包装在框中?

  6. 6

    如何将<a>元素包装在表中?

  7. 7

    如何将jQuery内容包装在H标签中?

  8. 8

    如何将列表项包装在link_to中?

  9. 9

    如何将UILabel包装在原型单元中

  10. 10

    如何将python模块包装在tar中?

  11. 11

    如何将子元素包装在父标签中?

  12. 12

    如何将 div 包装在新的 div 中?

  13. 13

    如何将类包装在高阶组件中?

  14. 14

    将异步功能包装在Promise中

  15. 15

    如何将常量放入 React 组件中,包装在 recompose 中

  16. 16

    这是将readFileSync包装在Promise中的正确方法吗

  17. 17

    如何将长代码行包装在google-code-prettify中

  18. 18

    斯威夫特:如何将异步方法包装在同步方法中?

  19. 19

    HAML遍历集合-如何将子元素组包装在唯一的父级中?

  20. 20

    如何将每个Express JS请求包装在域或trycatch中

  21. 21

    如何将img宽度的百分比包装在特定的div宽度中?

  22. 22

    Flutter:如何将数学方程式包装在容器中?

  23. 23

    如何将Flex Cloumns包装在移动设备的单行中

  24. 24

    如何将长代码行包装在google-code-prettify中

  25. 25

    如何将WCF客户端包装在共享库中

  26. 26

    如何将jQuery Justified Gallery包装在Ember组件中?

  27. 27

    如何将参数传递给JS函数而不将其包装在匿名函数中?

  28. 28

    如何将这组li元素包装在ul容器中?

  29. 29

    如何将现有的iOS代码包装在新的Appcelerator模块中?

热门标签

归档