为什么。然后(resolvecallback,recublcallback)在promise.race polyfill中的表现与。(resolvecallback)。

发布于 2025-02-11 07:36:13 字数 1324 浏览 0 评论 0原文

我正在使用以下代码段编写Polly.race()方法的polyfill。

const promise = new Promise((resolve, reject) => {
  resolve('promise resolved');
});

const promise2 = Promise.resolve('promise2 resolved');

function raceCopy(promises) {
  return new Promise(function (resolve, reject) {
    for (var index = 0; index < promises.length; index++) {
        Promise.resolve(promises[index])
          .then(resolve)
          .catch(reject);
    }
  });
}

raceCopy([Promise.reject('copy rejected'), promise, promise2])
  .then((response) => console.log(response))
  .catch((error) => console.error(error));

但是,它没有在控制台中给出“拒绝”错误,而是显示“承诺已解决”。我不明白它如何以及为什么这样工作?

我尝试的是

  1. 我使用的
Promise.race([Promise.reject('copy rejected'), promise, promise2])
 .then((response) => console.log(response))
 .catch((error) => console.error(error));
  1. ?其次,我更改了Racecopy()的实现。这样的东西,
function raceCopy(promises) {
  return new Promise(function (resolve, reject) {
    for (var index = 0; index < promises.length; index++) {
      Promise.resolve(promises[index]).then(resolve, reject);
    }
  });
}

它也给出了正确的结果。

我不了解什么? 如果所有实现都是相同的,那么为什么所有结果都不相同?我在这里想念什么?

I was writing polyfill for Promise.race() method using the below code snippet.

const promise = new Promise((resolve, reject) => {
  resolve('promise resolved');
});

const promise2 = Promise.resolve('promise2 resolved');

function raceCopy(promises) {
  return new Promise(function (resolve, reject) {
    for (var index = 0; index < promises.length; index++) {
        Promise.resolve(promises[index])
          .then(resolve)
          .catch(reject);
    }
  });
}

raceCopy([Promise.reject('copy rejected'), promise, promise2])
  .then((response) => console.log(response))
  .catch((error) => console.error(error));

But instead of giving the error "copy rejected" in the console, it is showing "promise resolved". I do not understand How and Why it is working like this?

What I tried?

  1. I used the existing Promise.race() API, and it is giving me the correct result "copy rejected".
Promise.race([Promise.reject('copy rejected'), promise, promise2])
 .then((response) => console.log(response))
 .catch((error) => console.error(error));
  1. Second, I changed the implementation of the raceCopy(). Something like this,
function raceCopy(promises) {
  return new Promise(function (resolve, reject) {
    for (var index = 0; index < promises.length; index++) {
      Promise.resolve(promises[index]).then(resolve, reject);
    }
  });
}

And It is also giving the correct result.

What I'm not understanding?
If all the implementations are the same then Why are the results not the same for all? What am I missing here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哆兒滾 2025-02-18 07:36:13

我已经进行了一些测试,并找到了有趣的结果。请注意,这只是我发现测试的事情,因此可能不是100%准确的;深入研究Ecmascript文档将肯定会更正确。

基本上,您的原始代码不起作用的原因是。然后.catch
这是因为在这种情况下如何排队。让我们使用以下输入显示一个示例:

var promises = [Promise.reject('rejected'), Promise.resolve('resolved')];

如果在您的代码中使用链接,则是结果:

Promise.resolve(promises[index])
    .then(resolve)
    .catch(reject)

/*
-----------------------
Microtask queue
-----------------------
- .then of index 0, then enqueue the catch
- .then of index 1 (which resolve the promises)
- .catch of index 0 (which gets ignored)

------------------------------------------------------------
If we reverse the chaining
*/

Promise.resolve(promises[index])
    .catch(reject)
    .then(resolve)

/*
-----------------------
Microtask queue
-----------------------
- .catch of index 0 (which reject the promises) and don't enqueue following .then
- .then of index 1 (which gets ignored)

*/

第一个.catch最终在Microtask队列的末尾,因为它已在第一个MicroTask中征用,而另一个在一开始就在主要任务中均被招募。

这只是猜测,但我认为它可以用这种方式来允许单个.catch捕获错误,即使有多个

修复它的正确方法可能是您在上一个示例中已经找到的方法。仅使用一个。然后,您仅排队一个微型掩体,它将以正确的方式处理它。

I've done some tests and found interesting results. Please be aware that this is just something I found out doing tests, so it might be not 100% accurate; a deep dive into the Ecmascript documentation would be more correct for sure.

Basically, the reason that your original code doesn't work is because of the chaining of .then and .catch.
It is because of how microtasks are queued in this situation. Let's show an example using the following input:

var promises = [Promise.reject('rejected'), Promise.resolve('resolved')];

if in your code you use chaining, this is the result:

Promise.resolve(promises[index])
    .then(resolve)
    .catch(reject)

/*
-----------------------
Microtask queue
-----------------------
- .then of index 0, then enqueue the catch
- .then of index 1 (which resolve the promises)
- .catch of index 0 (which gets ignored)

------------------------------------------------------------
If we reverse the chaining
*/

Promise.resolve(promises[index])
    .catch(reject)
    .then(resolve)

/*
-----------------------
Microtask queue
-----------------------
- .catch of index 0 (which reject the promises) and don't enqueue following .then
- .then of index 1 (which gets ignored)

*/

The first .catch ends up at the end of the microtask queue because it was enqueued in the first microtask, while the other .then are all enqueued in the main task at the very beginning.

This is just speculation, but I think that it works this way to allow for a single .catch to catch errors even if there are multiple .then before it.

The correct way to fix it is probably the one you already found in your last example. By only using one .then you are only queueing one microtask and it will handle it in the correct way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文