async await,回调函数,箭头函数this指向问题

async await,回调函数,箭头函数this指向问题

通过一个获取音乐api接口的例子,分别async函数来写获取歌曲列表方法,回调函数来写播放音乐方法,箭头函数来写播放mv方法。分别来看一下三个函数的this指向问题。接口地址为https://autumnfish.cn

async await例子

async serchMusic()用async修饰serchmusic这个方法。本质就是告诉编译器这是个async到异步处理函数。
通过let response = await axios来取代.then()的回调方法,可以有效避免回调地狱,使得代码看起来更像是同步执行。response去接受get请求的返回值

            async serchMusic() {
                var that = this;
                try{
                    let response = await  axios.get("https://autumnfish.cn/search?keywords=" + this.query)//请求一个在线音乐播放器地址
                    console.log(this);//结果为window
                    console.log(that);//结果为window
                    this.musiclist = response.data.result.songs;
                }catch (err){//处理错误或者不存在的请求
                    console.error(err);
                }
            },

.then回调函数

then()方法是异步执行就是当.then()前的方法执行完后再执行then()内部的程序这样就避免了。个人理解回调函数的this是指向window,不属于vue实例对象,所以无法来获取vue实例对象data里面的值。因为vue调用的playMusic方法所以第一次this指向vue对象实例。第二次.then()方法中的this因为.then()方法是属于window所以this也指向widow

            playMusic  :function (musicId) {
                var that = this;
                    console.log(this);//结果为vue实例
                    console.log(that);//结果为vue实例
                axios.get("https://autumnfish.cn/song/url?id=" + musicId)
                    .then(function (response) {
                    console.log(response);//异步函数的返回值
                    console.log(this);//指向window
                    console.log(that);//指向vue对象实例
                    console.log(this.query);//未定义
                    console.log(that.query);//歌曲名
                    that.musicUrl = response.data.data[0].url;
                    }, function (err) {
                    })
            },

箭头函数

箭头函数没有自己的this,使用的是上层作用域的this.所以就是指向vue实例可以获取vue对象data里的数据

            playMv: function (mvid) {
                    var that = this;
                    console.log(this);//结果为vue实例
                    console.log(that);//结果为vue实例
                axios.get("https://autumnfish.cn/mv/url?id=" + mvid)
                    .then((response)=> {
                    console.log(response);//异步函数的返回值
                    console.log(this);//指向vue对象实例
                    console.log(that);//指向vue对象实例
                    console.log(this.query);//歌曲名
                    console.log(that.query);//歌曲名
                        //console.log(response.data.data.url);
                        that.mvUrl = response.data.data.url;
                    })
                    
            }

完整代码复制运行就能播放歌曲

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>音乐接口</title>
    <script src="js/vue.js"></script>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css"
          integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
            integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
            crossorigin="anonymous"></script>
    <script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
    <style type="text/css">
        .global {
            background-size: 100% 100%;
            width: 100%;
            height: 900px;
        }
    </style>
</head>
<body>
<div id="app">
    <div class="global">
            

        <span>
            <input type="text" class="form-control" placeholder="请输入歌手" v-model="query" placeholder="输入歌曲名字"
                   @keyup.enter="serchMusic" >

            <button @click="serchMusic" type="button" class="btn btn-success"
                    >搜索</button>

        </span>
        <p style="font-size: 30px;color: red;position: absolute;top: 60%;left: 15%;"></p>
        <ul style="position: absolute;left: 0%; top: 40% ; color: red;">

            <li v-for="item in musiclist" style="list-style:none;"><br>
                <button class="btn btn-success" href="#" @click="playMusic(item.id)">播放音乐</button>
                {{item.name}}
                <button class="btn btn-success" v-if="item.mvid!=0" @click="playMv(item.mvid)">播放mv</button>
            </li>


        </ul>
        <audio
                :src="musicUrl"
                controls
                autoplay
                loop
        ></audio>
        <video :src="mvUrl" controls="controls" autoplay="autoplay" >
            您的浏览器不支持 video 标签。
        </video>
    </div>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            query: "",
            musiclist: [],
            musicUrl: [],
            mvUrl: "",
        },
        methods: {
            async serchMusic() {
                var that = this;
                // console.log(this);//结果为vue实例
                // console.log(that);//结果为vue实例
                try{
                    let response = await  axios.get("https://autumnfish.cn/search?keywords=" + this.query)//请求一个在线音乐播放器地址
                    // console.log(this);//结果为vue实例
                    // console.log(that);//结果为vue实例
                    this.musiclist = response.data.result.songs;
                }catch (err){//处理错误或者不存在的请求
                    console.error(err);
                }
            },
            playMusic  :function (musicId) {
                    var that = this;
                    console.log(this);//结果为vue实例
                    console.log(that);//结果为vue实例
                axios.get("https://autumnfish.cn/song/url?id=" + musicId)
                    .then(function (response) {
                    console.log(response);//异步函数的返回值
                    console.log(this);//指向window
                    console.log(that);//指向vue对象实例
                    console.log(this.query);//未定义
                    console.log(that.query);//歌曲名
                    that.musicUrl = response.data.data[0].url;
                    }, function (err) {
                    })
            },
            playMv: function (mvid) {
                    var that = this;
                    console.log(this);//结果为vue实例
                    console.log(that);//结果为vue实例
                axios.get("https://autumnfish.cn/mv/url?id=" + mvid)
                    .then((response)=> {
                    console.log(response);//异步函数的返回值
                    console.log(this);//指向vue对象实例
                    console.log(that);//指向vue对象实例
                    console.log(this.query);//歌曲名
                    console.log(that.query);//歌曲名
                        //console.log(response.data.data.url);
                        that.mvUrl = response.data.data.url;
                    })
                    
            }
        },
    })
</script>
</body>
</html>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页