2021-01-19

异步(二)回调地狱

一.回调地狱

在谈到回调地狱发生的情况和解决办法,需要先了解ajax请求

先列出服务器提供的数据接口:app.get('/data1', (req, res) => { res.send('hi')})app.get('/data2', (req, res) => { res.send('hello')})app.get('/data3', (req, res) => { res.send('nihao')}) // 启动监听app.listen(3000, () => { console.log('running...')})

 

原生ajax请求步骤

let xhr = new 

 

函数封装

上面有data1,data2,data3,三次请求,那么就需要写三个ajax,这时就会想到用函数来封装

function queryData(path,callback){ let xhr = new 'get','url'+path) xhr.send(null); xhr.onreadystatechange = function(){  if(xhr.readyState===4 && xhr.status ===200)  {   let ret = xhr.responseText;   callback(ret)  }  }}//调用queryData('data1',function(ret){ console.log(ret)})

 

如何形成的回调地狱

如果想按顺序获取接口'data1','data2','data3' 中的数据,就会进行下面的操作

queryData('data1',function(ret){ console.log(ret) //按顺序第一个输出:hi queryData('data2',function(ret){  console.log(ret) //第二个输出 hello  queryData('data3',function(ret){   console.log(ret) //第三个输出:你好  }) })})如果这里有100个,1000个,甚至更多的请求呢,那真是一场灾难

 

promise方式

为了改造上面的回调函数问题,诞生了promise.promise其实就是一种语法糖(代码形式发生改变,但是功能不变)  

 

function queryData(path) { return new Promise(function(resolve, reject) { // 需要在这里处理异步任务 var xhr = new 'get','' + path); xhr.send(null); xhr.onreadystatechange = function() {  // 该函数何时触发?xhr.readyState状态发生变化时  if(xhr.readyState != 4) return;  if(xhr.readyState == 4 && xhr.status == 200) {  // 获取后台数据  var ret = xhr.responseText;  // 成功的情况  resolve(ret);  } else {  // 失败的情况  reject('服务器错误');  } } })}


分析

queryData('data1') .then(ret=>{ console.log(ret)  // 顺序输出第一个结果为:hi // 如果在then方法中没有返回Promise实例对象,那么下一个then由默认产生的Promise实例对象调用 }) .then(ret=>{ console.log('-------------------' + ret)  // 顺序输出第二个结果为:----------------------undefined // 如果在then中显式地返回一个具体数据,那么下一个then可以获取该数据 return 456; }) .then(ret=>{ console.log('-------------------' + ret)  // 顺序输出第三个结果为:----------------------456 })

promist对象除了.then方法外,还有两个方法可以通过,调用,其中finally是ES&中新增的方法

.catch(ret=>{ // 发生错误时触发 console.log('error')}).finally(ret=>{ // 无论结果成功还是失败都触发:一般用于释放一些资源 console.log('finally')})

 

async和await 进行解决

function queryData(path) { return new Promise(function(resolve, reject) { // 需要在这里处理异步任务 var xhr = new 'get','' + path); xhr.send(null); xhr.onreadystatechange = function() {  // 当readyState值不为0的时候直接返回  if(xhr.readyState != 4) return;  if(xhr.readyState == 4 && xhr.status == 200) {  // 获取后台数据  var ret = xhr.responseText;  // 成功的情况  resolve(ret);  } else {  // 失败的情况  reject('服务器错误');  } } })} async function getAllData() { // await执行流程是顺序执行 let ret1 = await queryData('data1'); let ret2 = await queryData('data2'); let ret3 = await queryData('data3'); console.log(ret1) console.log(ret2) console.log(ret3)}getAllData();

需要注意一点:async函数的返回值是Promise实例对象

async function getAllData() { // await执行流程是顺序执行 let ret1 = await queryData('data1'); return 'hello';}var ret = getAllData();console.log(ret)  // 这里输出一个promise对象,并且resolve的数据为helloret.then(res=>{ console.log(res)  // 这里输出结果为:hello})

 

以上内容来自:https://www.cnblogs.com/belongs-to-qinghua/p/11161140.html

 

结合promise,做一个小案例,模拟一个对话页面,输入文字,通过接口,获取机器人的对话,同时将对话转为语音放出来

<script>  const baseUrl = "";  window.onload = function () {  document   .querySelector("#btnSend")   .addEventListener("click", function () {   let str = document.querySelector("#ipt").value.trim();   if (!str) {    alert("信息不能为空");    return;   }   appendContent(str, "right");   document.querySelector("#ipt").value = "";   //获取机器人信息   getJiQiRXX(str)    .then((res) => {    appendContent(res.data.info.text);    return getJiQiYY(res.data.info.text);    })    .then((res) => {    // console.log("语音内容", res);    document.querySelector("audio").src = res.voiceUrl;    });   });  };  function getJiQiRXX(spoken) {  return new Promise((resolve, reject) => {   //请求机器人信息   let xhr = new "get", baseUrl + "/api/robot?spoken=" + spoken);   xhr.send(null);   xhr.onreadystatechange = function () {   if (xhr.readyState === 4) {    if (xhr.status === 200) {    let data = JSON.parse(xhr.responseText);    resolve(data);    // console.log(xhr.responseText);    } else {    reject("请求失败,请稍后再试");    }   }   };  });  }  function getJiQiYY(text) {  return new Promise((resolve, reject) => {   let xhr = new "get", baseUrl + "/api/synthesize?text=" + text);   xhr.send(null);   xhr.onreadystatechange = function () {   if (xhr.readyState === 4) {    if (xhr.status === 200) {    let data = JSON.parse(xhr.responseText);    resolve(data);    } else {    reject("请求失败,请稍后再试");    }   }   };  });  }  // function scrollChange() {}  function appendContent(str, who) {  let li = document.createElement("li");  li.className = who === "right" ? "right_word" : "left_word";  li.innerHTML = `<img src="img/${   who === "right" ? "person02.png" : "person01.png"  }" /> <span>${str}</span>`;  document.querySelector("#talk_list").appendChild(li);  //滚动  document.querySelector("#talk_list").scrollTop = document.querySelector(   "#talk_list"  ).scrollHeight;  } </script>

 

结合async await,做一个小案例,模拟一个对话页面,输入文字,通过接口,获取机器人的对话,同时将对话转为语音放出来

const baseUrl = "http://www.liulongbin.top:3006";  window.onload = function () {  document   .querySelector("#btnSend")   .addEventListener("click", function () {   let str = document.querySelector("#ipt").value.trim();   if (!str) {    alert("信息不能为空");    return;   }   appendContent(str, "right");   document.querySelector("#ipt").value = "";   // //获取机器人信息   // getJiQiRXX(str)   // .then((res) => {   //  appendContent(res.data.info.text);   //  //获取语音   //  return getJiQiYY(res.data.info.text);   // })   // .then((res) => {   //  // console.log("语音内容", res);   //  document.querySelector("audio").src = res.voiceUrl;   // });   getAllData(str);   });  };  async function getAllData(spoken) {  //获取机器人信息  let res1 = await getJiQiRXX(spoken);  appendContent(res1.data.info.text);  //获取语音信息  let res2 = await getJiQiYY(res1.data.info.text);  document.querySelector("audio").src = res2.voiceUrl;  }  function getJiQiRXX(spoken) {  return new Promise((resolve, reject) => {   //请求机器人信息   let xhr = new 

  

 









原文转载:http://www.shaoqun.com/a/512259.html

跨境电商:https://www.ikjzd.com/

四海商舟:https://www.ikjzd.com/w/1516

002315焦点科技:https://www.ikjzd.com/w/1831


一.回调地狱在谈到回调地狱发生的情况和解决办法,需要先了解ajax请求先列出服务器提供的数据接口:app.get('/data1',(req,res)=>{res.send('hi')})app.get('/data2',(req,res)=>{res.send('hello')})app.get('/data3&
中国邮政邮乐网:中国邮政邮乐网
custommade:custommade
口述:被小三拆散家庭我做小三报复男人(5/5):口述:被小三拆散家庭我做小三报复男人(5/5)
澳门有哪些免费巴士?这些巴士去哪里?:澳门有哪些免费巴士?这些巴士去哪里?
干货分享|亚马逊卖家如何重新刊登滞留库存?:干货分享|亚马逊卖家如何重新刊登滞留库存?

No comments:

Post a Comment