-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathasync-func.js
More file actions
67 lines (61 loc) · 1.75 KB
/
async-func.js
File metadata and controls
67 lines (61 loc) · 1.75 KB
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/**
* 简单实现 async/await
*
* @param {GeneratorFunction} generatorFn
* @example
* ```js
* const testAsync = asyncToGenerator(test)
* testAsync().then(val => {})
* ```
*/
function asyncToGenerator(generatorFn) {
return function (...args) {
const gen = generatorFn.apply(this, args)
return new Promise((resolve, reject) => {
function step(key, arg) {
let result
try {
result = gen[key](arg)
} catch (error) {
return reject(error)
}
const { value, done } = result
if (done) {
return resolve(value)
} else {
return Promise.resolve(value).then(
(val) => step('next', val),
(err) => step('throw', err)
)
}
}
step('next')
})
}
}
const getData = () =>
new Promise((resolve) => setTimeout(() => resolve(Date.now()), 1000))
/**
* async 函数会被编译成 generator 函数 (babel 会编译成更本质的形态,这里我们直接用 generator)
*
* @example
* ```js
* async function test() {
* const data = await getData()
* console.log('data: ', data)
* const data2 = await getData()
* console.log('data2: ', data2)
* return 'success'
* }
* ```
*/
function* testG() {
// await 被编译成了 yield
const data = yield getData()
console.log('data: ', data)
const data2 = yield getData()
console.log('data2: ', data2)
return 'success'
}
const testGAsync = asyncToGenerator(testG)
testGAsync().then(console.log)