diamont1001/blog

利用Promise的状态机制,避免函数被重复调用

Opened this issue · 0 comments

Promise 的实例对象有三个状态:pending, fulfilled, rejected,如下图:

image

我们可以理解成两种状态:「初始化(pending)」和「结束(resolve|reject)」,而且它是一个不可逆的过程。也就是说,一个 promise 新对象一开始是 pending 状态,一旦调用了 resolve 或者 reject 后,就会变成结束状态,不可逆。

下面举几个栗子:

async function foo() {
  setTimeout(function() {
    return Promise.resolve();
  }, 1000);
}

看上面这个函数,也是常用的一种写法,每次调用它都会延时1秒。

async function foo() {
  return new Promise(resolve => {
    setTimeout(function() {
      resolve();
    }, 1000);
  })
}

同样的,这个函数也是一样效果。但是有一点不一样的是,这个函数它返回的是一个新实例化的 Promise 对象,我们可以利用它来实现一些不一样的场景。

比如一个页面,它的初始化配置信息需要从网络上请求,其实就是异步获取,有了 Promise,我们可以这么解决:

async function foo() {
  return new Promise(resolve => {
    setTimeout(function() {
      resolve(123);
    }, 1000);
  })
}

// 初始化的时候去请求
const handler = foo();

// 其他地方查询配置信息,有两种可能:
// - foo 函数还没请求完:会等待完成后再返回
// - foo 函数已请求完:马上返回
const config = await handler; // 123

这样,它只会请求一次网络请求,以后每次查询都会马上返回。