【问题标题】:Are promises only for async operations?承诺仅适用于异步操作吗?
【发布时间】:2016-02-27 20:56:36
【问题描述】:

我想知道是否可以在我的倒数计时器中使用 Promise。我的代码如下所示:

function countdown(duration, callback) {
  ...
}

function sayHi() {
  console.log('hi');
}

我通过做类似的事情来称呼它

countdown(15, sayHi);

有什么办法可以代替吗?

countdown(15).then(sayHi); 

Here 是我当前代码的 JSFiddle。

【问题讨论】:

  • 那将是一个异步操作,不是吗。 ?
  • 谷歌一下promise,然后你就可以回答你的问题了。
  • 真的吗?我的countdown 函数中的所有代码都是同步的,this 就是现在的样子。我基本上只是手动调用回调。
  • "Promise 是否仅适用于异步操作?" - 是的。 “有没有办法我可以改用countdown(15).then(sayHi);” - 是的。向我们展示... 是什么,我们或许可以帮助您完成转型。
  • 倒计时意味着异步。我的坏

标签: javascript promise es6-promise


【解决方案1】:

是的,promise 是一种“隐藏”回调的方式。对于您的示例,您可以使用这样的承诺:

function countdown(duration) {
    return new Promise(function (resolve, reject) {
        // wait for duration and resolve
        setTimeout(function () {
            resolve();
        }, duration);
    });
}

function sayHi() {
    console.log('hi');
}

countdown(1000).then(sayHi);

【讨论】:

  • 不是所有的回调都可以使用 Promise 隐藏。
  • 你有例子吗?它没有将回调作为参数传递,而是转到then(),不需要进行其他更改。
  • Many examples,实际上 :-) 你的代码很好,我只是不同意“promises 是一种“隐藏”回调的方法”的一般性。
  • 啊,我明白了。我刚刚意识到,当多次调用回调(同步或异步)时,promise 不能(容易?)替换它。这就是管道/流在 NodeJS 中发挥作用的地方。有趣。
  • 完全正确 - 在这种情况下永远不能使用承诺。它们只适用于只调用一次(通常是异步的)的回调。
【解决方案2】:

是的,您可以在自己的特定时间resolve他们,例如。使用闭包来避免同时来自多个调用的不良响应。

function countdown(duration, callback) {
 var deferred = Promise.defer();
    (function(duration,deferred){setTimeout(function(){
        deferred.resolve();
    },duration);
  })(duration,deferred);
}

上一个已经过时了检查这个。

  function countdown(duration, callback) {
     return new Promise(function (resolve, reject) {
            setTimeout(function () {
                resolve();
            }, duration);
        });


}

【讨论】:

  • 没有Promise.defer函数。
  • 那些不是 ES6 的承诺。您链接的页面上的第二句话是弃用通知。
  • 它已经过时了,我很久以前就用过了,谢谢
  • @ngLover countdown 返回TypeError: Promise resolver undefined is not a function
【解决方案3】:
function countdown(duration) {
  return new Promise(function(resolve, reject) {
    var interval = setInterval(function() {
      console.log(duration--);
      if (!duration) {
        clearInterval(interval);
        resolve();
      }
    }, 1000);
  });
}
countdown(15).then(function() { console.log("DONE"); });

【讨论】:

  • 承诺setTimeout 并将其用作异步原语更合理。在setInterval 中使用console.log 就像您所做的那样不会给您带来任何承诺的优势。
  • @Bergi:承诺是为了倒计时结束,就像在 OP 的帖子中一样。 console.log 模拟了倒计时期间的 UI 更新。我想我从字面上理解了“倒计时”。
  • 是的,但如果你使用 Promise,你也应该使用 Promise 进行 UI 更新 :-)
  • 为什么要重新发明setTimeout
【解决方案4】:

promise 适用于任何不一定会立即运行的操作。

Javascript 是单线程的。所以如果你调用一个函数,它必然会立即在同一个线程上运行。 Promise 是稍后运行代码的一种便捷方式(仍然在同一个线程上,但作为不同事件处理程序的一部分)。

所以在超时的情况下,当回调应该稍后调用时,使用promise是一个好主意。

如果您不确定是使用 Promise 还是简单的回调,两者的目的或多或少是相同的,但 Promise 通常会使代码更具可读性。

ES7 async-await 更具可读性!

【讨论】:

  • 感谢您的解释!给你点赞。还要感谢 async-await 的链接,看起来很酷
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-16
  • 2021-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多