/

如何將回調轉換為async/await

如何將回調轉換為async/await

我有一些使用回調函數的程式碼。不涉及太多實現細節,以下是要點:

1
2
3
4
5
6
7
8
const uploadFile = (callback) => {
// 上傳文件,然後將文件位置通過回調函數返回
callback(location)
}

uploadFile((location) => {
// 執行後續操作
})

如上所示,我調用uploadFile函數,當它完成所需操作後,就會調用該回調函數。

但是我希望在整個程式碼中都使用async/await,因此我決定在這裡使用async/await來替代回調函數。

這是我所做的:我將uploadFile函數的主體代碼用return new Promise()包裹起來,並在獲取到要返回的數據後調用resolve()

1
2
3
4
5
6
7
8
const uploadFile = () => {
return new Promise((resolve, reject) => {
// 上傳文件,然後通過回調函數返回文件位置
resolve(location)
})
}

const location = await uploadFile()

現在,我可以在第一層級中使用location數據,而不是它被包裹在回調函數中。

這有助於讓我的代碼更加整潔,並更好地理解它。

如果您有興趣,這是實際函數的完整代碼,您可以在其中看到此概念的具體示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const uploadFile = (fileName, id, callback) => {
const fileContent = fs.readFileSync(fileName)

const params = {
Bucket: process.env.AWS\_BUCKET\_NAME,
Key: `file.jpg`,
Body: fileContent
}

s3.upload(params, (err, data) => {
if (err) {
throw err
}
callback(data.Location)
})
}

uploadFile(files.logo.path, job.id, async (location) => {
await prisma.job.update({
where: { id: job.id },
data: {
logo: location
}
})
})

下面是我的轉換結果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
const uploadFile = (fileName, id) => {
return new Promise((resolve, reject) => {
const fileContent = fs.readFileSync(fileName)

const params = {
Bucket: process.env.AWS\_BUCKET\_NAME,
Key: `job-${id}.jpg`,
Body: fileContent
}

s3.upload(params, (err, data) => {
if (err) {
reject(err)
}
resolve(data.Location)
})
})
}

handler.post(async (req, res) => {
const files = req.files
const body = req.body

const job = await prisma.job.create({
data: {
...body,
created\_at: new Date().toISOString()
}
})

const location = await uploadFile(files.logo.path, job.id)

await prisma.job.update({
where: { id: job.id },
data: {
logo: location
}
})

res.redirect(`/jobs/${job.id}/payment`)
})

tags: [“async/await”, “callback”, “Promise”, “JavaScript”]