preface


[JavaScript]

Plain text view
Copy the code

?
1
2
3
4
5
6
7
async
function
func() {

try
{

let res = await asyncFunc()

}
catch
(e) {

/ /...

}
}















[JavaScript]

Plain text view
Copy the code

?
1
2
3
4
5
6
7
async
function
func() {

let [err, res] = await errorCaptured(asyncFunc)

if
(err) {

/ /... Error trapping

}

/ /...
}








[JavaScript]

Plain text view
Copy the code

?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
// development
async
function
func() {

let res = await asyncFunc()

/ /... Other logic
}
// release
async
function
func() {

try
{

let res = await asyncFunc()

}
catch
(e) {

/ /...

}

/ /... Other logic
}






Loader principle


[JavaScript]

Plain text view
Copy the code

?
1
2
3
4
{

test: /\.vue$/,

use:
"vue-loader"
.
}









Implementation approach






AST

An abstract syntax tree is an abstract representation of the syntax structure of source code. It represents the syntactic structure of a programming language as a tree, with each node in the tree representing a structure in the source code



[JavaScript]

Plain text view
Copy the code

?
1
2
let a = 1
let b = a + 5
























Recommend a very useful AST viewing tool, AST Explorer, a more intuitive view of how code is translated into abstract syntax tree





[JavaScript]

Plain text view
Copy the code

?
1
2
3
async
function
func() {

await asyncFunc()
}











[JavaScript]

Plain text view
Copy the code

?
1
2
3
4
5
6
7
async
function
func() {

try
{

await asyncFunc()

}
catch
(e) {

console.log(e)

}
}












Loader development








[JavaScript]

Plain text view
Copy the code

?
01
02
03
04
05
06
07
08
09
10
11
12
13
const parser = require(
"@babel/parser"
)
const traverse = require(
"@babel/traverse"
).
default
module.exports =
function
(source) {

let ast = parser.parse(source)

traverse(ast, {

AwaitExpression(path) {

/ /...

}

})

/ /...
}





[JavaScript]

Plain text view
Copy the code

?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
const parser = require(
"@babel/parser"
)
const traverse = require(
"@babel/traverse"
).
default
const t = require(
"@babel/types"
)
module.exports =
function
(source) {

let ast = parser.parse(source)

traverse(ast, {

AwaitExpression(path) {

let tryCatchAst = t.tryStatement(

/ /...

)

/ /...

}

})
}





[JavaScript]

Plain text view
Copy the code

?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const parser = require(
"@babel/parser"
)
const traverse = require(
"@babel/traverse"
).
default
const t = require(
"@babel/types"
)
const parser = require(
"@babel/parser"
)
const traverse = require(
"@babel/traverse"
).
default
const t = require(
"@babel/types"
)
module.exports =
function
(source) {

let ast = parser.parse(source)

traverse(ast, {

AwaitExpression(path) {

let tryCatchAst = t.tryStatement(

// try clause (required)

t.blockStatement([

t.expressionStatement(path.node)

]),

/ / catch clause

t.catchClause(

/ /...

)

)

path.replaceWithMultiple([

tryCatchAst

])

}

})

/ /...
}



Method for manipulating Node nodes





[JavaScript]

Plain text view
Copy the code

?
1
let res = await asyncFunc()


[JavaScript]

Plain text view
Copy the code

?
1
res = await asyncFunc()


[JavaScript]

Plain text view
Copy the code

?
1
await asyncFunc()





[JavaScript]

Plain text view
Copy the code

?
01
02
03
04
05
06
07
08
09
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
42
43
44
45
46
47
48
49
50
51
52
const parser = require(
"@babel/parser"
)
const traverse = require(
"@babel/traverse"
).
default
const t = require(
"@babel/types"
)
module.exports =
function
(source) {

let ast = parser.parse(source)

traverse(ast, {

AwaitExpression(path) {

if
(t.isVariableDeclarator(path.parent)) {
// Variable declaration

let variableDeclarationPath = path.parentPath.parentPath

let tryCatchAst = t.tryStatement(

t.blockStatement([

variableDeclarationPath.node
// Ast

]),

t.catchClause(

/ /...

)

)

variableDeclarationPath.replaceWithMultiple([

tryCatchAst

])

}
else
if
(t.isAssignmentExpression(path.parent)) {
// Assign expression

let expressionStatementPath = path.parentPath.parentPath

let tryCatchAst = t.tryStatement(

t.blockStatement([

expressionStatementPath.node

]),

t.catchClause(

/ /...

)

)

expressionStatementPath.replaceWithMultiple([

tryCatchAst

])

}
else
{
// await expression

let tryCatchAst = t.tryStatement(

t.blockStatement([

t.expressionStatement(path.node)

]),

t.catchClause(

/ /...

)

)

path.replaceWithMultiple([

tryCatchAst

])

}

}

})

/ /...
}





[JavaScript]

Plain text view
Copy the code

?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
const parser = require(
"@babel/parser"
)
const traverse = require(
"@babel/traverse"
).
default
const t = require(
"@babel/types"
)
const core = require(
"@babel/core"
)
module.exports =
function
(source) {

let ast = parser.parse(source)

traverse(ast, {

AwaitExpression(path) {

/ / same as above

}

})

return
core.transformFromAstSync(ast).code
}









conclusion