javascript - 如何在 when 函数中延迟 promise

标签 javascript angularjs ecmascript-6

如何延迟 promise 链?我需要这个,因为我想在继续执行脚本之前等待 CSS 动画完成。

该函数的目的是打开一个 View 。如果 View 尚未打开,则打开它(通过更改类),等待 css 动画,继续。如果 View 已经打开,则什么都不做并继续。

我想这样调用函数: (它是 Angular Controller 中的一个函数)

$scope.openView(viewId).then(function() {              
     $scope.openAnotherView(anotherViewId);
});


/** Function to open some view **/
$scope.openView = function (viewId) {
    function timeout(delay) {
        return new Promise(function(resolve, reject) {
            $timeout(resolve, delay);
        });
    }

    // Check if view is already open
    if ($scope.viewId != viewId) {
         $scope.viewId = viewId;             

         // get data from ajaxcall (also a promise)
         return MyService.getData(viewId).then(function(data) {
             // add data to view
             // change class to open view
             // this is working ok!
         }).then(function() { 
             return timeout(30000 /* some large number (testing purpose) */ )
         });
    } else {
         // view is already open, so return here we don't have to wait
         // return empty promise, with no timeout
         return new Promise(function(resolve, reject) {
             resolve()
         });     
    }
}

此代码有效,但延迟无效。我的方法可以吗?我在这里缺少什么?


编辑 1:根据@sdgluck 的建议改进了代码


编辑 2:对主要问题的一些澄清:

进一步澄清主要问题: 我可以在我的代码中使用这个结构吗?

// code doesnt know wheter to wait or not
// can the Promise do this?
openView().then(function() {              
     openAnotherView();
}

结果 1:

浏览器将调用 openView(),但由于它已经打开,它只会立即调用 openAnotherView()(没有延迟)。

结果 2:

View 未打开,因此 openView() 将打开它,然后延迟(或者如@Dominic Tobias 指出的那样,添加一个事件列表?)然后调用 openAnotherView() 经过一些延迟。

感谢您的帮助!

编辑 3:添加了一个 fiddle 来解释问题 http://jsfiddle.net/C3TVg/60/

最佳答案

要延迟 promise ,只需在等待时间后调用 resolve 函数即可。

new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve();
  }, 3000); // Wait 3s then resolve.
});

您的代码的问题在于您正在返回一个 Promise,然后在该 Promise 的 then 中您正在创建另一个 Promise 并期望原始 promise 等待它 - 我'恐怕这不是 promise 的工作方式。您必须在 promise 函数中完成所有等待,然后调用 resolve:

编辑:这不是真的,您可以在任何 then 中延迟 promise 链:

function promise1() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('promise1');
      resolve();
    }, 1000);
  })
  .then(promise2);
}

function promise2() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('promise2');
      resolve();
    }, 1000);
  });
}

function promise3() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('promise3');
      resolve();
    }, 1000);
  });
}

promise1()
  .then(promise3)
  .then(() => {
    console.log('...finished');
  })

然而,这不是等待 css 动画的好方法。不如听transitionend事件:

element.addEventListener('transitionend', onTransitionEnd);
element.classList.add('transition-me');

请注意,如果您使用的是 animation 而不是 transition,同样的概念也适用,但使用 animationend事件。

关于javascript - 如何在 when 函数中延迟 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34653095/

相关文章:

javascript - 如何使用 React 和 Redux 测试带有嵌套容器的组件?

javascript - 如何进行正确的 Node.js 错误回调?

javascript - AngularJS - 专注于嵌套滚动中的对象

javascript - 工厂和 Controller 依赖错误

javascript - 找不到此 JavaScript 代码中的错误所在。对 'class'语法不太熟悉

javascript - 从无状态功能组件动态渲染按钮

javascript - 如何将 anchor 标记添加到字符串 Prop ?

javascript - 如何从 Angular 中的指令获取值

Javascript ES6 - 在不同的 .js 文件中导入函数或变量之前等待模块完成执行

javascript - highstock 将平移功能附加到 mousedown