与 promises 一起使用时 setTimeout 的行为不明确

Ambiguous behavior of setTimeout when used with promises

我想 运行 每 x 秒在承诺中使用一个异步方法,直到满足特定条件,然后调用 resolve() 来解决承诺。我尝试使用两种方法(如下所示)。第二种方法是使用 IIFE 设计的,并给出了正确的结果,但在第一种方法中,setTimeout 方法仅 运行ning 一次,但根据 def。 setTimeout 它应该在指定的时间后无限期地执行回调,直到调用 clearTimeout() 。任何人都可以向我解释为什么我在第一种方法中没有得到所需的输出吗?

方法 1

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

方法二

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

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

可以用递归函数实现

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