【问题标题】:Rewrite promises to async/await when setTimeout() is used [duplicate]使用 setTimeout() 时重写异步/等待的承诺[重复]
【发布时间】:2019-11-13 18:07:45
【问题描述】:

我有两个用 Promise 编写的函数:

const resolvedDelay = (value, ms) => new Promise(resolve => setTimeout(() => resolve(value),ms));
const rejectedDelay = (value, ms) => new Promise((resolve,reject) => setTimeout(() => reject(value),ms));

我尝试通过 async/await 重写它们。这是我的错误尝试:

const resolvedDelay = async (value, ms) => setTimeout(() => value,ms); // I haven't reference to `resolve` here... :(
const rejectedDelay = async (value, ms) => setTimeout(() => {throw new Error(value)},ms);

怎么做才对?

【问题讨论】:

  • 只有当你想在函数中使用await 承诺时,使用async 才有意义。由于setTimeout 与promise 无关,因此您也不能使用async。第一种方式是唯一正确的方式。

标签: javascript asynchronous promise async-await


【解决方案1】:

通常这样做是为了将 setTimeout 转换为可重用的 Promise,然后是可等待的。

const delay = time => new Promise(res => setTimeout(res, time));

const resolvedDelay = async (value, ms) => {await delay(ms); return value;}; 
const rejectedDelay = async (value, ms) => {await delay(ms); throw Error(value);};

【讨论】:

    【解决方案2】:

    您必须先有一个承诺,才能对await 做任何有用的事情。而且,由于setTimeout() 不会创建承诺,也不会解决或拒绝承诺,因此您必须创建承诺并将其绑定到setTimeout() 回调,就像您在第一个代码块中所做的那样。

    您的第二个代码块只调用setTimeout() 并立即返回。将它包装在async 中使其返回一个承诺,但当函数在调用setTimeout() 后返回时,该承诺会立即解决。因此,当setTimeout() 回调触发时,您必须解决或拒绝一个承诺,而仅使用async 函数包装器无法做到这一点。

    因此,async/await 在创建您的两个函数时并没有真正的用处。您手动创建 Promise 的第一组函数就是这里的方法。

    当然,调用者可以将await 与您的第一组函数一起使用,无需更改即可。

    【讨论】:

      【解决方案3】:

      这就是我的做法,但我不知道有一种方法可以使它保持为箭头函数。

      function resolvedDelay(value, ms) {
          return new Promise(resolve => {
              setTimeout(() => {
                  resolve(value);
              }, ms);
          });
      }
      
      function rejectedDelay(value, ms) {
          return new Promise((resolve, reject) => {
              setTimeout(() => {
                  resolve(value);
              }, ms);
          });
      }
      
      async function callFunctions() {
          const resolved = await resolvedDelay();
          const rejected = await rejectedDelay();
      
          // Do whatever you want with them now
      }
      

      【讨论】:

        猜你喜欢
        • 2018-09-02
        • 2018-04-17
        • 2018-12-18
        • 2017-06-15
        • 1970-01-01
        • 2018-08-31
        • 2022-01-22
        • 2021-04-01
        • 1970-01-01
        相关资源
        最近更新 更多