1. 首页
  2. css

CSS为什么使用reduce()顺序解析承诺有效

在不使用Promise对象的情况下编写异步JavaScript就像闭着眼睛烤蛋糕一样。这是可以做到的,但会很混乱,你可能会烧了自己。
我不会说这是必要的,但你知道的。真是太好了。不过,有时候,它需要一些帮助来解决一些独特的挑战,例如,当您试图依次解决一堆承诺时,像这样的技巧非常方便,例如,当您通过AJAX进行某种批处理时。你想让服务器处理一堆事情,但不是一次处理所有事情,所以你需要在一段时间内将处理过程隔开。
排除那些有助于简化这项任务的包(比如Caolan McMahon的异步库),对于顺序解析承诺,最常用的建议解决方案是使用Array.prototype.reduce()。你可能听说过这个。取一个集合,并将它们简化为一个值,例如:
let => {return accumulator + item;}, 0); // {return>
Or, in a more modern format:
let => {await previousPromise;return methodThatReturnsAPromise(nextID);}, Promise.resolve());
这很整洁!但在最长的一段时间里,我只是吞下了这个解决方案,并将这段代码复制到了我的应用程序中,因为它\”起作用了\”。这篇文章让我试图理解两件事:
1. 为什么这种方法能起作用?为什么我们不能用其他的方法来做同样的事情?为什么这样做有效?
记住,reduce()的主要目的是将一堆东西\”简化\”为一件东西,它在循环运行时将结果存储在accumulator中。但那不一定是数字。循环可以返回它想要的任何东西(比如承诺),并在每次迭代中通过回调循环该值。值得注意的是,无论accumulator值是多少,循环本身都不会改变其行为—包括其执行速度。它只是在线程允许的范围内以最快的速度在集合中滚动。
这很难理解,因为它可能与您认为在循环过程中发生的事情相反(至少,它对我是这样)。当我们用它来依次解决承诺时,reduce()循环实际上一点也没有变慢。它是完全同步的,尽可能快地完成正常的事情,就像往常一样。
看看下面的代码片段,注意到回调中返回的承诺完全没有阻碍循环的进程。
function methodThatReturnsAPromise(nextID) {return new Promise((resolve, => {console.log(`Resolve! ${dayjs().format(\”hh:mm:ss\”)}`);resolve();}, 1000);});}[1,2,3].reduce( (accumulatorPromise, => {return methodThatReturnsAPromise(nextID);});}, Promise.resolve());
在我们的控制台中:
\”Loop! 11:28:06\”\”Loop! 11:28:06\”\”Loop! 11:28:06\”\”Resolve! 11:28:07\”\”Resolve! 11:28:08\”\”Resolve! 11:28:09\”
承诺按照我们预期的顺序解决,但是循环本身是快速、稳定和同步的。在看了reduce()的MDN polyfill之后,这是有意义的。while()循环一次又一次地触发callback()并不是异步的,这就是引擎盖下发生的事情:
while (k
With all that in mind, the real magic occurs in this piece right here:
return>
Each time our callback fires, we return a promise that resolves to another promise. And while reduce()不等待任何解决方案发生,它提供的优势是能够在每次运行后将某些内容传递回同一个回调中,reduce()独有的特征。因此,我们能够构建一个承诺链,将承诺分解为更多的承诺,使每件事都变得美好有序:
new Promise( (resolve, => {// Promise #2return result;}).then(>
All of this should also reveal why we can\”t just return a single, new promise each iteration. Because the loop runs synchronously, each promise will be fired immediately, instead of waiting for those created before it.
[1,2,3].reduce( (previousPromise, =>>
In our console:
\”Loop! 11:31:20\”\”Loop! 11:31:20\”\”Loop! 11:31:20\”\”Resolve! 11:31:21\”\”Resolve! 11:31:21\”\”Resolve! 11:31:21\”
是否可以等到所有的处理完成后再做其他事情?对。reduce()的同步性并不意味着你不能在每一个项目都处理完之后再举办派对。看:
function methodThatReturnsAPromise(id) {return new Promise((resolve, => {console.log(`Processing ${id}`);resolve(id);}, 1000);});}let => {return => {console.log(\”Resolution is complete! Let\”s party.\”)});
既然我们在回调中返回的只是一个链式的承诺,那么当循环完成时我们得到的就是:一个承诺。在那之后,我们可以随心所欲地处理它,即使在reduce()运行了很长时间之后也是如此。为什么其他数组方法都不起作用?
请记住,在reduce()的掩护下,我们不是在等待我们的回电完成后才开始下一个项目。它是完全同步的。其他所有这些方法也是一样的:
– Array.prototype.map()
– Array.prototype.forEach()
– Array.prototype.filter()
– Array.prototype.some()
– Array.prototype.every()

CSS为什么使用reduce()顺序解析承诺有效 为WP2原创文章,链接:https://www.wp2.cn/css/css%e4%b8%ba%e4%bb%80%e4%b9%88%e4%bd%bf%e7%94%a8reduce%ef%bc%88%ef%bc%89%e9%a1%ba%e5%ba%8f%e8%a7%a3%e6%9e%90%e6%89%bf%e8%af%ba%e6%9c%89%e6%95%88/