简体   繁体   English

函数之间错误的 promise.all() 用法?

[英]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:在附加的代码中,我希望事件触发并按以下顺序记录:

  • the "before" string “之前”字符串
  • the list of "... detected" “...检测到”的列表
  • the list of "done with ..." “完成...”的列表
  • the "after" string “之后”字符串

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:我看到您的代码至少有两个问题,解释了您得到的结果:

  1. Your 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数组,因此您需要一个普通函数。
  2. .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.logthen()期望函数稍后执行,因此您必须将其更改为.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM