消除异步传染性是指在 JavaScript 中处理异步操作时,确保不会出现代码逻辑的混乱或错误。

以下是几种消除异步传染性的常见方法:

使用 async/await:async/await 是 ES2017 引入的语法糖,可以更优雅地处理异步操作。通过在函数前面加上 async 关键字,可以在函数内部使用 await 来等待异步操作的结果。这样可以避免回调地狱(callback hell),使异步代码看起来更像是同步代码。

示例代码:

1
2
3
4
5
6
7
8
async function example() {
try {
const data = await asyncFunction(); // 等待异步操作的结果
console.log(data); // 处理异步操作的结果
} catch (error) {
console.error(error); // 处理错误
}
}

使用 Promise:Promise 是一种用于处理异步操作的标准语法,可以避免回调地狱。通过使用 Promise,可以将异步操作封装为一个 Promise 对象,并使用 then() 方法处理异步操作的结果,同时可以使用 catch() 方法处理错误。

示例代码:

1
2
3
4
5
6
7
asyncFunction()
.then(data => {
console.log(data); // 处理异步操作的结果
})
.catch(error => {
console.error(error); // 处理错误
});

使用回调函数:在某些情况下,可能需要使用回调函数来处理异步操作。确保将回调函数作为异步函数的参数传递,并在异步操作完成后调用回调函数。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function asyncFunction(callback) {
// 异步操作完成后调用回调函数
setTimeout(() => {
const data = '异步操作结果';
callback(null, data); // 第一个参数为错误对象,第二个参数为异步操作的结果
}, 1000);
}

asyncFunction((error, data) => {
if (error) {
console.error(error); // 处理错误
} else {
console.log(data); // 处理异步操作的结果
}
});

以上是常见的消除异步传染性的几种方法,根据具体的场景和需求,可以选择适合的方法来处理异步操作。

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
68
69
70
71
72
73
// 定义一个执行函数
function eliminateAsync(func){
let i = 0
let cache = [] // 用于缓存数据
let _originMain = main // 把异步函数赋值到一个变量供后面执行
window.main = (...arg)=>{ // 重新定义异步函数
// 判断缓存中有没有数据,第一次肯定没有
if(cache[i]){
// 如果有缓存数据
// 如果状态是fulfilled的,就返回缓存数据
if(cache[i].status === 'fulfilled'){
return cache[i].data
}else{
// 如果异步函数执行错误了就返回错误信息
throw cache[i].error
}
}
let result = {
status: 'pending',
data: null,
error: null
}
// 保存缓存信息,第一次缓存数据是假缓存
cache[i++] = result
// 执行一函数,第一次不等待函数执行完,执行下面的抛出错误 throw pro
let pro = _originMain(...arg).then(
(resp)=> {
// 把数据缓存起来
result.status = 'fulfilled'
result.data = resp
},
(err)=> {
// 把错误数据缓存起来
result.status ='rejected'
result.error = err
}
)
throw pro
}
try{
func()
}catch(err){

if(err instanceof Promise){
const reRun = ()=>{
i = 0
func()
}
// 接收到抛出的错误后,再等待异步函数执行完成后重新运行传进来的函数,下次运行
// 就能拿到缓存的数据了,因为异步函数已经执行完毕,缓存已经保存了
err.then(reRun,reRun)
}
}
}
function main(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('收到反馈和案说法')
},1000)
})
}
function f1(){
return main()
}
function f2(){
// 这里就不需要增加async和await了
console.log(11) // 其实你会发现这个打印执行了2次,明白其中道理就会知道为什么会打印2次
let user = f1()
console.log(user);
}


eliminateAsync(f2) // 一秒过后打印 ‘收到数据并返回信息’