gpt4 book ai didi

javascript - promise 的动态顺序执行

转载 作者:行者123 更新时间:2023-11-30 20:33:29 25 4
gpt4 key购买 nike

我有一个动态数量的 promise ,我需要按顺序运行。我了解如何按顺序运行 promise ,但我没有成功地通过许多可能不同的 promise 使其动态化。

这是我发现的一种静态方式 How to resolve promises one after another? :

function waitFor(timeout) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`Finished waiting ${timeout} milliseconds`);
}, timeout);
});
}

waitFor(1000).then(function(result) {
$('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
return waitFor(2000);
}).then(function(result) {
$('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
return waitFor(3000);
}).then(function(result) {
$('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div id="result"></div>

我想做同样的事情,但不是 3 个嵌套的 promise ,我想要任何我想要的数字。你能帮助我吗 ?

非常感谢!!

最佳答案

使用 Promises 可以通过三种基本方法来完成此任务。

  1. .reduce() 模式。

function waitFor(timeout) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`Finished waiting ${timeout} milliseconds`);
}, timeout);
});
}

var timeouts = [1000, 2000, 2000, 3000, 1000],
sequence = tos => tos.reduce((p,c) => p.then(rp => waitFor(c))
.then(rc => console.log(`${rc} @ ${new Date().getSeconds()}`)), Promise.resolve());

sequence(timeouts);

  1. 递归模式。

function waitFor(timeout) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`Finished waiting ${timeout} milliseconds`);
}, timeout);
});
}

var timeouts = [1000, 2000, 2000, 3000, 1000],
sequence = ([to,...tos]) => to !== void 0 && waitFor(to).then(v => (console.log(`${v} @ ${new Date().getSeconds()}`), sequence(tos)));

sequence(timeouts);

  1. 从左侧模式扫描。

scanl 模式将一个接一个地对 promise 进行排序,但一旦完成,您还可以访问临时 promise 解决方案。这在某些情况下可能很有用。如果您要懒惰地构建一个异步树结构(仅在需要时从节点分支),您需要能够访问以前的 promise 解决方案。

为了在JS中实现scanl功能,首先我们要实现它。

var scanl = (xs, f, acc) => xs.map((a => e => a = f(a,e))(acc))

我们为 scanl 提供 xs ,这是这个特定示例中的超时数组,f 是一个回调函数,它接受 acc(累加器)和 e(当前项)并返回新的累加器。累加器值(临时 promise 解决方案)映射到超时数组上,以便在需要时访问。

function waitFor(timeout) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`finished waiting ${timeout} milliseconds`);
}, timeout);
});
}

var timeouts = [1000, 2000, 2000, 3000, 1000],
scanl = (xs, f, acc) => xs.map((a => e => a = f(a,e))(acc)),
proms = scanl(timeouts, // input array
(a,t,r) => a.then(v => (r = v, waitFor(t))) // callback function
.then(v => (console.log(`${r} and ${v}`),
`${r} and ${v}`)),
Promise.resolve(`Started with 0`)); // accumulator initial value

// Accessing the previous sub sequential resolutions
Promise.all(proms)
.then(vs => vs.forEach(v => console.log(v)));
.as-console-wrapper {
max-height: 100% !important
}

关于javascript - promise 的动态顺序执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50089543/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com