[英]Wrong promise.all() usage between functions?
I made this dummy code to have a better understanding on how promises work, mimicking a more complex software that I have to "promisify".我制作了这个虚拟代码,以便更好地理解 Promise 的工作原理,模仿我必须“承诺”的更复杂的软件。 In the attached code, I wanted the events to fire and be logged in the following order:
在附加的代码中,我希望事件触发并按以下顺序记录:
But as you can see if you run it, the "after" string is printed between steps 2 and 3. Clearly, I must be doing something wrong in handling async logic.但是正如您在运行它时所看到的那样,在第 2 步和第 3 步之间打印了“after”字符串。显然,我在处理异步逻辑时一定做错了。 Thanks for your help!
谢谢你的帮助!
const obj = { "rows": [{ "type": "A", "value": 0 }, { "type": "B", "value": 0 }, { "type": "C", "value": 0 }] } let promises = []; function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } const alter_value = async(row, to_add, time) => { await delay(time); row.value = row.value + to_add; console.log("done with " + row.type); return true; } const two = async() => { obj.rows.forEach(async(row) => { switch (row.type) { case "A": console.log("A detected"); promises.push(alter_value(row, 1, 1000)) promises.push(alter_value(row, 2, 1800)) break; case "B": console.log("B detected"); promises.push(alter_value(row, 5, 1400)) break; case "C": console.log("C detected"); promises.push(alter_value(row, 200, 2400)) break; } }); return promises; } const one = async() => { console.log("before"); Promise.all(two()).then(console.log("after")); } one();
I see at least two issues with your code, explaining the result you're getting:我看到您的代码至少有两个问题,解释了您得到的结果:
two
function should not be async
.two
函数不应该是async
。 async
functions return an implicit Promise
. async
函数返回一个隐式的Promise
。 Here you just want to return an array of Promise
s that you already construct yourself, so a normal function is what you need.Promise
数组,因此您需要一个普通函数。.then(console.log("after"))
will execute the console.log
right away: then()
expects a function to execute later, so you have to change it to .then(() => console.log("after"))
. .then(console.log("after"))
将立即执行console.log
: then()
期望函数稍后执行,因此您必须将其更改为.then(() => console.log("after"))
。 This becomes:这变成:
const obj = { "rows": [{ "type": "A", "value": 0 }, { "type": "B", "value": 0 }, { "type": "C", "value": 0 }] }; function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } const alter_value = async (row, to_add, time) => { await delay(time); row.value = row.value + to_add; console.log("done with " + row.type); return true; }; const two = () => { const promises = []; obj.rows.forEach(async(row) => { switch (row.type) { case "A": console.log("A detected"); promises.push(alter_value(row, 1, 1000)); promises.push(alter_value(row, 2, 1800)); break; case "B": console.log("B detected"); promises.push(alter_value(row, 5, 1400)); break; case "C": console.log("C detected"); promises.push(alter_value(row, 200, 2400)); break; } }); return promises; }; const one = async () => { console.log('before'); Promise.all(two()).then(() => console.log('after')); }; one();
Note that, as an alternative to .then()
, you can simply use await
on Promise.all
as well, to make your code more consistent:请注意,作为
Promise.all
.then()
的替代方法,您也可以简单地在Promise.all
上使用await
,以使您的代码更加一致:
await Promise.all(two());
console.log('after');
It looks like the OP requests synchronous behavior.看起来 OP 请求同步行为。
Demo Outline演示大纲
function modVal(i, value, time)
parameters are derived from the async function syncro()
parameter: const sync
an array of objects.函数
modVal(i, value, time)
参数派生自异步函数syncro()
参数: const sync
对象数组。 Each object contains the index of obj.rows
, the value at that index obj.rows[i].value
, and the time for the timeout in the Promise of modVal()
.每个对象都包含
obj.rows
的索引、该索引处的值obj.rows[i].value
以及modVal()
Promise 中的超时时间。
Parameters and Arguments: const sync = [{r: 0, v: 1, t: 1000}, ...];
参数和参数:
const sync = [{r: 0, v: 1, t: 1000}, ...];
seq.r: obj.rows[
number ]
seq.r: obj.rows
obj.rows[
数字]
seq.v: obj.rows[seq.r].value +=
number seq.v: obj.rows
obj.rows[seq.r].value +=
number
seq.t: ...resolve(obj.rows[i].value += value),
number ); seq.t:
...resolve(obj.rows[i].value += value),
obj.rows ...resolve(obj.rows[i].value += value),
number );
sync
array is iterated by a for...of
loop. sync
数组由for...of
循环迭代。 On each iteration await modVal()
is called synchronously.在每次迭代中
await modVal()
被同步调用。
let obj = { "rows": [{ "type": "A", "value": 0 }, { "type": "B", "value": 0 }, { "type": "C", "value": 0 }] } const sync = [{ r: 0, v: 1, t: 1000 }, { r: 0, v: 2, t: 1800 }, { r: 1, v: 5, t: 1400 }, { r: 2, v: 200, t: 2400 }]; const syncro = async(sync) => { const modVal = (i, value, time) => { return new Promise(resolve => { setTimeout(() => resolve(obj.rows[i].value += value), time); }); } for (let seq of sync) { await modVal(seq.r, seq.v, seq.t); console.log(JSON.stringify(obj.rows)); } } syncro(sync);
.as-console-row.as-console-row::after { content:''; padding:0; margin:0; border:0; width:0; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.