这个问题有很多答案,但大多数答案都会同步承诺的解决方案(即执行结束,而不是执行的开始)。
This solution假设我们已经有了一系列函数:
var funcs = [foo, bar, baz, qux];
如何在不执行函数的情况下创建此类数组?我试过这个:
var promises = [];
for (i = 0 ; i < 3, ++i){
promises.push( someFunction(i) )
}
function someFunction(i) {
return new Promise((resolve, reject) => {
console.log(i);
resolve(i);
});
}
在for循环结束时,将填充promises数组,但someFunction
已执行4次。使用Promise.all
或Q
序列只需解析序列。
如何实现这些功能开始的真正同步?特别是:
foo().then(bar).then(baz).then(qux);
更新(使用异步功能的简单解决方案):
执行此操作的简单方法是使用async
函数和await
。有关在循环中调用promise的示例,请参阅this answer,其中每个promise将在前一个promise被解析时被调用。
答案 0 :(得分:1)
问题是
promises.push( someFunction(i) )
当您填充promises
数组时,每次在将someFunction
值传递给.push
方法之前调用{p: ..., val: ...}
。所以它可以根据需要提前执行。
解决方法是不要打电话。这并不容易实现,所以我在考虑一点(但丑陋)黑客。我引入了一个对象callPromise
,它包含promise函数和promise函数的值。如果要提供多个值,只需传递一个数组。 apply()
方法会将其转换为函数参数。函数var promises = [];
for (let i = 0 ; i < 3; ++i){
promises.push( {p: someFunction, val: i} );
}
promises.push({p: anotherFunction, val: [100,33]});
promises.push( {p: someFunction, val: 4} );
function someFunction(i) {
return new Promise((resolve, reject) => {
console.log('someFunction, i: ' + i);
resolve(i);
});
}
function anotherFunction(i1, i2) {
return new Promise((resolve, reject) => {
console.log('anotherFunction, i1: ' + i1 + ', i2: ' + i2);
resolve(i);
});
}
function callPromise(prom) {
if(Object.prototype.toString.call(prom.val) !== '[object Array]') prom.val = [prom.val];
return prom.p.apply(null, prom.val);
}
console.log('before loop');
let result = callPromise(promises[0]);
for (let i = 1 ; i < promises.length; ++i) {
result = result.then(callPromise(promises[i]));
}
以正确的方式处理函数的执行。
可能有人提出了更好的解决方案,但这是我能想到的快速解决方案。
以下是按顺序调用promises的示例。我已经添加了一个额外的函数(如果你有另一个函数有一个以上的参数)作为PoC。
@GetMapping(value = "/")
public ResponseEntity<ExampleObj> findByName(@RequestParam("name") String name) {
...
&#13;
答案 1 :(得分:0)
您只需要传递函数的名称,而不传递参数。 在你的例子中,你打电话
someFunction(i)
- 你传递参数i,所以这是一个函数调用。 您应该仅按名称推送功能。每个函数的参数是在前一个promise中解析的值。
function someFunction(i) {
return new Promise((resolve, reject) => {
console.log(i);
resolve(i+1); // increase the value here
});
}
通过这种方式,参数将传递给下一个增加1的函数。但是对于链中的第一个函数,您应该传递参数。 像
这样的东西 someFunction(0).then(someFunction).then(someFunction)
(在此解决方案中,您不需要阵列。)