javascript - 在 javascript 中使用 Promises 运行代码时出现问题
问题描述
节目说明
Create 3 functions:
FuncA – will receive a string and returns it’s length
FuncB – will receive an array of strings and returns their total lengths (using
funcA) after 2 seconds.
FuncC - will receive an array of arrays of strings and returns their total lengths
(using FuncB)
我的解决方案是
function funcA(s)
{
return s.length
}
function funcB(arr)
{
return new Promise(resolve =>
{
setTimeout(() =>
{
let total = 0;
arr.forEach(element => {
total += funcA(element)
});
resolve(total)
},2000)
})
}
function funcC(arr)
{
return new Promise(resolve =>
{
let isFirst = true
//a <=> total
let total = arr.reduce(async (a,b) =>
{
if(isFirst) {
isFirst = false
return (await funcB(a) + await funcB(b))
}
else {//a <=> total
return (a + await funcB(b))
}
})
resolve(total)
})
}
运行的是:
funcC([["aa","bbb","tyui"],["ccc"],["dfghj","aedtfr"]]).then(x => console.log(x) )
结果是: [object Promise]11
问题是什么?
解决方案
这真是令人费解。
- 不要将业务逻辑放在
setTimeout
回调中。只解决 promise,然后在 promisethen
回调中或在await
. - 始终将初始值传递给
reduce
! 这将使它适用于空数组,并且它将消除对那种非常奇怪的isFirst
逻辑的需要。 total
已经是一个承诺。不要不必要地将其包装在new Promise
!
这些建议将导致
function funcA(s) { return s.length }
function funcB(arr) {
return new Promise(resolve => {
setTimeout(resolve, 2000);
}).then(() => {
let total = 0;
arr.forEach(element => {
total += funcA(element)
});
return total;
});
}
function funcC(arr) {
return arr.reduce(async (a,b) => {
return await a + await funcB(b)
}, Promise.resolve(0))
}
但是,reduce
并不真正适合异步工作。您应该在 中使用循环方法funcC
,并reduce
在funcB
更适合的地方使用:
async function funcB(arr) {
await new Promise(resolve => {
setTimeout(resolve, 2000);
});
return arr.reduce((total, element) => total + funcA(element), 0);
}
async function funcC(arr) {
let total = 0;
for (const b of arr) {
total += funcB(b);
}
return total;
}
推荐阅读
- python - 使用外部文件在气流中动态创建任务
- sql - 如何在 Windows 上使用 Vscode 解决 UNABLE_TO_GET_ISSUER_CERT_LOCALLY
- pandas-groupby - 如何在多索引数据帧上使用 Talib 计算随机 RSI?
- javascript - 编写了两个 JavaScript 函数,但其中一个似乎使我的网站崩溃
- android - 在 buildSrc 中访问 ApplicationVariants
- r - 为什么 dplyr 和 ifelse 一起使用时 r 会显示错误?
- terminal - 如何使用 h 和 l 横向滚动更少?
- javascript - 删除所有文本后如何使受控文本字段再次为空?SPFX 反应/打字稿
- c# - 根据功能区 VSTO Excel 上打开的工作簿文件设置选项卡的可见性
- wordpress - ACF 元键字段在后网格插件 wordpress 中字段为“关系”类型时显示数组