setTimeout外部和setTimeout内部的getStates()函数中,promise(p1、p2、p3)的执行方式如何不同?

const p1 = new Promise((res) => setTimeout(() => res(100), 100));
const p2 = new Promise((res) => setTimeout(() => res(200), 200));
const p3 = new Promise((res, rej) => setTimeout(() => rej(300), 100));

async function getStates() {
  console.log(await promiseState(p1));
  console.log(await promiseState(p2));
  console.log(await promiseState(p3));
}

console.log("Immediately after initiation:");
getStates();
setTimeout(() => {
  console.log("After waiting for 100ms:");
  getStates();
}, 100);

promiseState功能是from MDN并使用Promise.race:

function promiseState(promise) {
  const pendingState = { status: "pending" };

  return Promise.race([promise, pendingState]).then(
    (value) =>
      value === pendingState ? value : { status: "fulfilled", value },
    (reason) => ({ status: "rejected", reason }),
  );
}

这都是MDN Promise.race page名中的一个例子.

我认为所有Promises都应该返回pendingState对象,但setTimeout函数的情况并非如此.

推荐答案

promise (p1、p2、p3)如何以不同的方式执行

这是很多人对promise 的一个关键误解.promise 不是executed.promise 只是报告正在完成的事情,而不是do事情.这是observing个非同步动作结果的标准方式.

在该代码中,同步动作是计时器.当您create个promise(前三行代码)时,计时器就会启动.在new Promise返回promise之前,您传递new Promise的函数会被同步调用.该函数的工作是启动promise将报告的同步工作.因此,这三个promise中的每一个正在报告的工作都会在开始时启动一次,而不是稍后当您通过getStates观察它们时.

启动这些计时器后,您判断promise 状态两次:

  • 立即:这是在任何计时器都没有机会开火之前,因此所有promise 都显示悬而未决.
  • p1 ms后:此时,您的两个promise 已达成(p1p1 ms后兑现,p3p1 ms后被拒绝),其中一个仍在等待中(因为p2在200 ms内尚未达成).因此,您会看到p1已满足,p2正在等待,p3被拒绝.

关键是,promise 计时器在您创建promise 时开始,而不是稍后.


总而言之,检测promise 的状态是bad idea.这就是为什么promise 没有内置的方式来做到这一点.相反,编写代码,使其对promise 的履行和/或拒绝做出react ,而不必担心在建立这些react 时promise 的状态.像promiseState这样的函数是一种反模式,而不是在试图理解promise 如何工作的过程中非常有限的使用.即便如此,它也可能具有误导性--当您看到它时,这些信息可能已经过时了.

Javascript相关问答推荐

使用expressjs加载Nuxt版本=3.9.0(自定义服务器)

Promise.all立即跳到那时,而不是调用所有Promise

d3可排序表标题行中有收件箱--如何使收件箱不触发排序?

React状态变量在使用++前置更新时引发错误

有条件的悲剧

Redux工具包查询(RTKQ)端点无效并重新验证多次触发

扫描qr code后出错whatter—web.js

在vercel throws上部署带有gunjs的sveltekit应用无法找到模块./' lib/文本编码'

浮动Div的淡出模糊效果

获取Uint8ClampedArray中像素数组的宽度/高度

如何解决useState错误—setSelect Image不是函数''

我正在建立一个基于文本的游戏在react ,我是从JS转换.我怎样才能使变量变呢?

S文本内容和值不必要的不同

Chart.js-显示值应该在其中的引用区域

单个HTML中的多个HTML文件

未加载css colored颜色 ,无法将div设置为可见和不可见

以编程方式聚焦的链接将被聚焦,但样式不适用

expo 联系人:如果联系人的状态被拒绝,则请求访问联系人的权限

打字脚本中方括号符号属性访问和拾取实用程序的区别

将Auth0用户对象存储在nextjs类型脚本的Reaction上下文中