【问题标题】:Is promise.all used to de-capsulate promise value?promise.all 是用来解封装 promise 值的吗?
【发布时间】:2020-09-20 23:15:39
【问题描述】:

我试图了解 Promise.all() 到底在做什么。

据我所知, promise 是在 javascript 中为异步执行保存返回值的东西。

因此,promise 封装的值(?)不能在同步运行中直接访问。

(术语警告!我将使用类比来说明我如何看待 promise 和 promise.all())

要直接访问承诺值, 我需要剥掉一个叫做promise的外壳,它是 promise.all 在异步函数的末尾。

在这个“剥离”之后,我可以访问一个同步可用的值。

我对 Promise.all 的理解正确吗?

非常感谢。

示例来自 mdn 网站。

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
// expected output: Array [3, 42, "foo"]

同步执行“console.log()”成功处理了所有承诺和同步值 (const promise2)。

如果我不像下面这样剥离承诺外壳,

Promise.all([promise2, promise3]).then((values) => {
  console.log(values);
  console.log(promise1)
});

js吐出来的值如下。

数组 [42, "foo"]

[对象承诺]

请随时批评我的类比和 如果我理解有误,请告诉我。

提前谢谢你。

【问题讨论】:

  • 没有。你不能“解开”一个承诺——没有办法立即访问一个未来的价值。 Promise.all 的重点是将 promise1.then(value1 => console.log(value1)); promise2.then(value2 => console.log(value2)); 更改为 Promise.all([promise1, promise2]).then(([value1, value2]) => console.log(value1, value2)); 值在 then 回调中异步访问。

标签: javascript asynchronous promise


【解决方案1】:

您的类比是一个非常有趣的类比,但我相信这是对 Promise 工作原理的普遍看法。 Promise 是管理 defered 值的构造 - 在某个阶段与时间相关的值。使用“包装”一词听起来像是价值已经存在,而实际上它很可能还没有。

promise 可用于表示来自 API 的响应,或者可能来自数据库的查找 - 这两者都需要 时间 - 这是同步代码无法处理的。你可能会提出一个请求,并得到一个承诺作为回应。然后,您可以使用这个 Promise 作为助手来获取您想要接收的值。

当您调用promise.then(value => ...) 时,then 函数会等待,直到值准备好。在 Promise 中,必须调用 resolve(value) 才能触发 then 函数(注意,也可以通过 reject 拒绝 Promise,在这种情况下会触发 promise.catch)。这是一个完整的例子:

const promise = new Promise(resolve => {
  setTimeout(() => {
    resolve(10);
  }, 2000);
});

promise.then(value => {
  // This fires after about 2 seconds
  console.log(value); // 10
});

所以这里的诀窍是可视化从承诺中获取结果发生在不同的“线程”上。可能在回调中或在await 调用之后。此外,一旦一个 promise 被解决,第二次调用 then 将返回与之前相同的值,并且它会更快,但仍然不是即时的,因为 promise 的“值”总是异步返回.

Promise.all 等待直到所有提供的承诺都解决了。 Promise.all 返回的是一个数组,其中包含按顺序的所有解析结果。因此,如果您有以下情况:

const promise1 = Promise.resolve(12); // Asynchronously returns 12
const promise2 = new Promise(resolve => {
  setTimeout(() => {
    resolve(10);
  }, 2000);
});

Promise.all([promise1, promise2]).then(results => {
 // results will be [12, 10], and will fire after about 2 seconds
});

// here, even though we're after the promise assignments,
// the values to BOTH of the promises are still not yet defined (not resolved)

TLDR; Promise 是一个类,一旦其提供的函数解析,它就会记录一个值。一旦由 promise 函数设置(通过调用 resolve 或 reject),then 方法将使用该值调用其回调。

【讨论】:

    猜你喜欢
    • 2018-02-06
    • 2020-06-23
    • 2018-04-10
    • 1970-01-01
    • 2022-11-03
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多