以下は、コードの一部であり、その合計(1,2,3,4,5,6)関数の戻り値が21のように、あなたは合計関数のasyncAdd関数を呼び出す必要があり、asyncAdd関数を変更することはできません、合計関数を改善してください。
/**
* 数値計算を完了するには、sum関数のこの関数を呼び出す
* @param {*} a 最初の値を追加するには
* @param {*} b 2番目の値を追加するには
* @param {*} callback コールバック関数の合計後
*/
function asyncAdd(a,b,callback) {
setTimeout(function(){
callback(null, a+b)
},1000)
}
/**
* 数値計算を完了するには、このメソッドでasyncAddメソッドを呼び出してください
* @param {...any} rest 入力パラメータ
*/
async function sum(...rest) {
// ここでコードを改善してほしい
}
let start = window.performance.now()
sum(1, 2, 3, 4, 5, 6).then(res => {
// sumメソッドを呼び出した後、結果が21であることを確認する。
console.log(res)
console.log(`プログラムの実行に費やされた時間の合計: ${window.performance.now() - start}`)
})
方法1:
async function sum(...rest) {
// 初期値として最初のものを取り出す
let result = rest.shift()
// for ofで残りを繰り返し、順番に加算する。
for(let num of rest) {
// Promiseを使用して合計結果を取得する
result = await new Promise(resolve => {
asyncAdd(result, num, (_,res) => {
resolve(res)
})
})
}
// 結果の実装に戻る
return result
}
// 実行に成功し、実行時間が6秒以上である
sum1(1, 2, 3, 4, 5,6).then(res => {
console.log(`結果は次のとおりである。:${res}`)
})
方法2:
async function sum(...rest) {
// 渡された値が2未満の場合は、直接返される
if (rest.length <= 1) {
return rest[0] || 0
}
const promises = []
// 値の配列を2つずつ繰り返し実行する
for (let i = 0; i < rest.length; i += 2) {
promises.push(
new Promise(resolve => {
// 残りの場合[i+1] は未定義であり、配列の長さは奇数であり、これは最後のものである。
if (rest[i + 1] === undefined) {
resolve(rest[i])
} else {
// 計算を実行するasyncAddを呼び出す
asyncAdd(rest[i], rest[i + 1], (_, result) => {
resolve(result)
})
}
})
)
}
// 最初の計算結果を取得する
const result = await Promise.all(promises)
// その後、最初の関数の結果を取得する。[3,7,11] を実行するために再びsumを呼び出す
return await sum(...result)
}
// 実行に成功し、実行時間は3秒以上4秒未満である。
sum1(1, 2, 3, 4, 5,6).then(res => {
console.log(`結果は次のとおりである。:${res}`)
})
方法3:
async function sum(...rest) {
let result = 0
// 隠し型変換、オブジェクト+ 数は、最初にオブジェクトのtoStringメソッドを呼び出す
const obj = {}
obj.toString = function() {
return result
}
const promises = []
for(let num of rest) {
promises.push(new Promise((resolve) => {
asyncAdd(obj, num, (_, res) => {
resolve(res)
})
}).then(res => {
// ここで結果の値を変更した後、obj.toString 関数の戻り値が変更され、次のsetTimeout呼び出しは、新しい値を使用する。
result = res
}))
}
await Promise.all(promises)
return result
}
// 実行に成功し、実行時間は1秒以上2秒未満である。
sum1(1, 2, 3, 4, 5,6).then(res => {
console.log(`結果は次のとおりである。:${res}`)
})