Js开发_Vue 回调&异步常用总结
① 第一步:callback
1. 方法回调
<template>
<div class="hello">
<button type="button" @click="setCallBack()"> testCallback </button>
</div>
</template>
<script>
export default {
name: 'callback',
data () {
return {
result: 0
}
},
methods: {
setCallBack() {
this.init((res) => {
console.log(res)
})
},
init(callback) {
setTimeout(() => {
if(Math.random() <= 0.6) {
callback(1)
} else {
callback(2)
}
}, 100)
}
}
}
</script>
2:回调地狱
<template>
<div class="hello">
<button type="button" @click="startCallback()"> test </button>
</div>
</template>
<script>
export default {
name: 'callback',
data () {
return {
result: 0
}
},
methods: {
startCallback(){
setTimeout(()=>{
console.log('callback 0.5秒',new Date());
setTimeout(()=>{
console.log('callback 0.4秒',new Date());
setTimeout(()=>{
console.log('callback 0.3秒',new Date());
setTimeout(()=>{
console.log('callback 0.2秒',new Date());
setTimeout(()=>{
console.log('callback 0.1秒',new Date());
}, 100);
}, 200);
}, 300);
}, 400);
}, 500);
}
}
}
</script>
3. 回调地狱的改善
<template>
<div class="hello">
<button type="button" @click="startCallback()"> test </button>
</div>
</template>
<script>
export default {
name: 'callback',
data () {
return {
result: 0
}
},
methods: {
call1(next){
setTimeout(()=>{
console.log('callback 0.5秒',new Date());
next();
},500);
},
call2(next){
setTimeout(()=>{
console.log('callback 0.4秒',new Date());
next();
},400);
},
call3(next){
setTimeout(()=>{
console.log('callback 0.3秒',new Date());
next();
},300);
},
call4(next){
setTimeout(()=>{
console.log('callback 0.2秒',new Date());
next();
},200);
},
call5(){
setTimeout(()=>{
console.log('callback 0.1秒',new Date());
},100);
},
startCallback(){
this.call1(()=>{
this.call2(()=>{
this.call3(()=>{
this.call4(()=>{
this.call5();
});
});
});
});
}
}
}
</script>
② 第二步 : Promise
Promise他将提供一种更加优雅的方法,让我们写回调函数。
Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法。
这么说用Promise new出来的对象肯定就有then、catch方法

Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
Promise对象有以下两个特点:
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败)。
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。
简单来说,Promise 就是用同步的方式写异步的代码,用来解决回调问题
<template>
<div class="hello">
<button type="button" @click="startCallback()"> test </button>
</div>
</template>
<script>
export default {
name: 'callback',
data () {
return {
result: 0
}
},
methods: {
call1(){
var p=new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('callback 0.5秒',new Date());
resolve();
},500);
});
return p;
},
call2(){
var p=new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('callback 0.4秒',new Date());
resolve();
},400);
});
return p;
},
call3(){
var p=new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('callback 0.3秒',new Date());
resolve();
},300);
});
return p;
},
call4(){
var p=new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('callback 0.2秒',new Date());
resolve();
},200);
});
return p;
},
call5(){
var p=new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('callback 0.1秒',new Date());
resolve();
},100);
});
return p;
},
startCallback() {
var self = this
this.call1()
.then(function(data){
return self.call2();
})
.then(function(data){
return self.call3();
})
.then(function(data){
return self.call4();
})
.then(function(data){
return self.call5();
})
}
}
}
</script>
第三步: Async/await/Promise
Async/await的主要益处是可以避免回调地狱(callback hell且以最接近同步代码的方式编写异步代码。
1.【方法中等待异步】
简单理解:async 是让方法变成异步 await是等待异步方法执行完毕。
<template>
<div class="hello">
<button type="button" @click="setPromise()"> test </button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
result: 0
}
},
methods: {
setPromise() {
var sleep = function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('ok');
// reject('error');
}, time);
})
};
var start = async function (self) {
try {
console.log('start async');
self.result = await sleep(3000); // 这里得到了一个返回错误
console.log('async后:'+ self.result); // 收到 ‘ok’
} catch (err) {
console.log(err); // 这里捕捉到错误 `error`
}
};
start(this)
console.log('async ago '+ this.result); // 收到 ‘ok’
}
}
}
</script>
2. 【复数异步方法】
复数异步方法顺序执行
<template>
<div class="hello">
<button type="button" @click="setPromise()"> test </button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
result: 0
}
},
methods: {
setPromise() {
let initIndex = function(self) {
Promise.resolve().then(function(){
console.log('step 1: start')
return self.init()
}).then(function(res) {
console.log('step 2: ' + res)
return self.getToken()
}).then(function(token) {
console.log('step 3: ' + token)
return self.getServerData(1)
}).then(function(data) {
console.log('step 4: ' + data)
return self.getServerData(2)
}).then(function(data) {
console.log('step 5: ' + data)
console.log('finish')
})
}
initIndex(this)
},
init() {
return new Promise((resolve, reject) => {
resolve('return true')
})
},
getToken() {
return new Promise((resolve, reject) => {
resolve('return token')
})
},
getServerData(data) {
return new Promise((resolve, reject) => {
resolve('return getServerData' + data)
})
}
}
}
</script>
3. 【复数异步方法】
复数方法优先执行
<template>
<div class="hello">
<button type="button" @click="setPromise()"> test </button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
result: 0
}
},
methods: {
setPromise() {
let $init = this.init()
let $getToken = this.getToken()
let $getServerData1 = this.getServerData(1)
let $getServerData2 = this.getServerData(2)
Promise.all([$init, $getToken, $getServerData1, $getServerData2]).then((values) => {
console.log(values)
console.log('finish')
});
},
init() {
return new Promise((resolve, reject) => {
resolve('return true')
})
},
getToken() {
return new Promise((resolve, reject) => {
resolve('return token')
})
},
getServerData(data) {
return new Promise((resolve, reject) => {
resolve('return getServerData' + data)
})
}
}
}
</script>
4.【循环中等待异步】
<template>
<div class="hello">
<button type="button" @click="setAgvList()"> test </button>
<ul v-for="item in items">
<li>{{item.count}}:{{item.name}}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
items: []
}
},
methods :{
setAgvList() {
const commonAsync = async() => {
for (var count = 0; count < 5; count++) {
var name = await this.getRobotByIndex(count)
var status = { count: count, name: name }
this.items.push(status)
}
console.log(this.items)
}
commonAsync()
},
async getRobotByIndex (agvIndex) {
return "hello world!" + agvIndex
}
}
}
</script>
浙公网安备 33010602011771号