与promises一起使用时setTimeout的模棱两可行为

时间:2018-12-11 11:26:16

标签: javascript node.js promise settimeout

我想每隔x秒在诺言中运行一个异步方法,直到满足特定条件,然后调用setTimeout来解决诺言。我尝试了两种方法(如下所示)。第二种方法是使用IIFE设计的,并且给出了正确的结果,但是在第一种方法中,setTimeout方法仅运行一次,但根据def。在clearTimeout()中,它应在指定的时间后无限期执行回调,直到调用function func2() { return new Promise((resolve, reject) => { setTimeout(() => { client.get('statuses/user_timeline', params1).then((response) => { // some code // some code if (condition is met) { return resolve() } else { // some code } }) }, 1000) }) } 为止。谁能向我解释为什么我在第一种方法中没有得到想要的输出?

方法1

function func2 () {
    return new Promise((resolve, reject) => {
        (function func1() {
            client.get('statuses/user_timeline', params1).then((response) => {
                //    some code
                if (condition is met) {
                    return resolve()
                } else {
                    //    some code
                    setTimeout(func1, 1000)
                }
            })
        })()
    }
}

方法2

<a href="{{pathFor 'Movie_Info' _id=movie._id}}">
  <img src={{movie.HomePoster}} class="popup-target" data-title="Title" data-content="Description">
</a>

2 个答案:

答案 0 :(得分:2)

setTimeout()仅执行一次功能,我认为您正在寻找setInterval()。它的工作方式相同,但是在无限期执行函数时,会在其上调用单元clearInterval()

这将是您的功能:

function func2() {
return new Promise((resolve, reject) => {
  let interval = setInterval(() => {

  client.get('statuses/user_timeline', params1).then((response) => {
    //    some code
    //    some code

    if (condition is met) {
      clearInterval(interval)
      return resolve()
  } else {
    //    some code
  }
})
}, 1000)
})
}

答案 1 :(得分:2)

您可以使用递归函数来实现

function waitForTimeline() {
   return client
       .get('statuses/user_timeline', params1)
       .then((response) => {
           if (condition is met) { return response }
           // In case the condition was not met, just call the same function
           // after a second
           return new Promise( ( resolve, reject ) => {
               setTimeout( () => {
                  waitForTimeline()
                      .then( resolve )
                      .catch( reject )
               }, 1000 );
           } );     
       }
};