运行 代码中的问题 javascript 中的 Promises
Problem in running code with Promises in javascript
程序说明
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))
结果是:
[对象承诺]11
问题是什么?
[修正答案]
你应该await a
而不是到处a
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(await a) + await funcB(b))
}
else {//a <=> total
return (await a + await funcB(b))
}
})
resolve(total)
})
}
这真是令人费解。
- 不要将业务逻辑放在
setTimeout
回调中。仅解析承诺,然后在承诺 then
回调中或在 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))
}
然而,。您应该在 funcC
中使用循环方法,而在 funcB
中使用 reduce
更合适:
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;
}
程序说明
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))
结果是: [对象承诺]11
问题是什么?
[修正答案]
你应该await a
而不是到处a
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(await a) + await funcB(b))
}
else {//a <=> total
return (await a + await funcB(b))
}
})
resolve(total)
})
}
这真是令人费解。
- 不要将业务逻辑放在
setTimeout
回调中。仅解析承诺,然后在承诺then
回调中或在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))
}
然而,funcC
中使用循环方法,而在 funcB
中使用 reduce
更合适:
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;
}