【问题标题】:how setTimeout works in promise in javascript?setTimeout 如何在 JavaScript 中实现 promise?
【发布时间】:2018-11-16 11:14:32
【问题描述】:

我有一个问题,我不知道 setTimeout 是如何工作的,我必须计时:

const start = new Date().getTime();
function a() {
  setTimeout(() => {
    console.log('output', new Date().getTime() - start);
  }, 3000);
}

setTimeout(a, 1000);

输出:4000

然后我像这样更改我的代码:

const start = new Date().getTime();
const p13 = new Promise((resolve,reject) => {
  setTimeout(() => {
    reject(new Error('error'));
  },3000);
});

const p14 = new Promise((resolve,reject) => {
  const s = new Date().getTime();
  setTimeout(() => {
    resolve(p13);
  },1000);
});

p14.then((value) => {
  console.log(value, 'value');
}).catch((error) => {
  const end = new Date().getTime();
  console.log('output:', end - start);
});

输出:3000,我不知道为什么?它应该输出 4000。为什么是 3000。

【问题讨论】:

    标签: javascript promise settimeout


    【解决方案1】:

    在 t = 0

    • 创建了一个以 timeout1 开头的承诺 p13,等待时间为 3 秒
    • 会创建一个以 timeout2 开头的承诺 p14,等待时间为 1 秒

    在 t = 1000

    • timeout2 触发回调函数,将p14 与promise p13 链接起来
    • timeout1 已经遍历了 1000ms

    在 t = 3000

    • timeout1触发回调函数,拒绝promise并计算输出

    让我们再举一个例子

    const start = new Date().getTime();
    const p13 = new Promise((resolve,reject) => {
      setTimeout(() => {
        const end = new Date().getTime();
        console.log('output:', end - start);
        reject(new Error('error'));
      },3000);
    });
    
    const p14 = new Promise((resolve,reject) => {
      const s = new Date().getTime();
      setTimeout(() => {
        resolve(p13);
      },1000);
    });
    
    setTimeout(function(){
      p14.then((value) => {
        console.log(value, 'value');
      }).catch((error) => {
        console.log('error');
      });
    }, 5000);

    如您在上面的示例中所见,承诺p13 的超时甚至在延迟5000 毫秒的setTimeout 的回调执行之前就被触发了。

    结论 - 当您创建一个promise 对象时,promise 对象的状态处于挂起状态,但是,实际功能会被触发。

    【讨论】:

      【解决方案2】:

      你的超时承诺是异步的。

      当你创建 p13 时,它直接开始了它的超时时间,也就是 3000。 它不是在等待 p14 的 1000。 (这是你的想法)

      详细了解您的代码预期结果:

      • 如果您在 p14 中输入任何小于 3000 的数字,它将以 300x 解析。如果你投入超过4000,那么它将被拒绝。 (虽然超时不是那么准确,所以它更像是 3000 / 4000 左右)

      【讨论】:

        【解决方案3】:

        当你创建一个新的 Promise 时,你作为构造函数参数传递的函数会立即执行。因此,p13 超时将在 Promise 创建后 3000 毫秒后调用拒绝 - 而不是在传递给 resolve 函数后 3000 毫秒。如果你希望你的 Promises 一个接一个地运行,你可以将你的代码重构为这样的:

        const start = new Date().getTime();
        const p13 = () => {
            return new Promise((resolve,reject) => {
                setTimeout(() => {
                    reject(new Error('error'));
                },3000);
            });
        }
        
        const p14 = new Promise((resolve,reject) => {
            const s = new Date().getTime();
            setTimeout(() => {
                resolve(p13());
            },1000);
        });
        
        p14.then((value) => {
            console.log(value, 'value');
        }).catch((error) => {
            const end = new Date().getTime();
            console.log('output:', end - start);
        });
        

        p13 现在是一个创建 Promise 的函数。该函数在 1000 毫秒后执行,新的 Promise 被创建并返回,并安排了另一个超时。第二次超时在 3000 毫秒后拒绝 Promise,因此在程序启动后 4000 毫秒后有效。

        【讨论】:

          【解决方案4】:

          这就是你如何使它达到 4000

          使 p13 成为一个函数

          解决(p13());

          现在您要等到 p14“完成”后才开始 p13

          const start = new Date().getTime();
          const p13 = () => new Promise((resolve,reject) => {
            setTimeout(() => {
              reject(new Error('error'));
            },3000);
          });
          
          const p14 = new Promise((resolve,reject) => {
            const s = new Date().getTime();
            setTimeout(() => {
              resolve(p13());
            },1000);
          });
          
          p14.then((value) => {
            console.log(value, 'value');
          }).catch((error) => {
            const end = new Date().getTime();
            console.log('output:', end - start);
          });

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-03-16
            • 1970-01-01
            • 2021-11-10
            • 2023-01-10
            • 1970-01-01
            • 2015-03-03
            • 2021-10-24
            • 2018-06-17
            相关资源
            最近更新 更多