奇怪的一些

本文详细介绍了JavaScript中的Promise机制,包括状态转换、then方法以及Promise.all和Promise.race的使用。同时,深入讲解了async/await语法,如何处理异步错误,以及在实际开发中的应用,如axios请求和文件上传。还提到了浏览器缓存问题和跨域问题的处理策略。
摘要由CSDN通过智能技术生成

1、请求200
但是请求回来的是html
网络里会写 200OK from disk cache
这个时候需要清除浏览器缓存
2、base64 引入失败 找一个js文件直接引入
require is not defined
import Base64 from ‘***’
https://blog.csdn.net/u011383596/article/details/116712729
3、promise
promise:异步编程解决方案
promise相当于一个状态机,拥有三种状态pending、fulfilled、rejected
(1)一个promise对象那个初始化的状态是pending,调用了resolve后会将promise的状态扭转为fulfilled,调用reject后会将promise的状态扭转为reject,这两种扭转一旦发生便不能扭转该promise到其它状态
(2)promise对象原型上有一个then方法,then方法会返回一个新的promise对象,并将回调函数return的结果作为该promise resolve的结果,then方法会在一个promise状态被扭转为fulfilled或rejected时被调用。then方法的参数为两个函数,分别为promise对象的状态被扭转为fulfilled和rejected对应的回调函数。

new Promise((res,rej)=>{})
Promise.all().then((res)=>{})
this.getFormData().then((res)=>{})
  getFormData () {
      return new Promise((resolve, reject) => {
        this.$http.get('', {
          params: { taskId: this.taskId }
        }).then(res => {
          resolve(res.data.result)
        })
      })
    },

构造一个promise对象,并将要执行的异步函数传入到promise的参数中执行,并且在异步执行结束后调用resolve()函数,就可以在promise的then方法中获取到异步函数的执行结果

new Promise((res,rej)=>{
  setTimeout(()=>{
    resolve()
  },1000)
}).then()

Promise.all接收一个promise对象数组作为参数,只有全部的promise都已经变成fulfilled状态后才会继续后面的处理。Promise.all本身返回的也是一个promise

const promise1 = new Promise((res,rej) => {
  setTimeout(()=>{
    resolve('promise1')
  },1000)
})
const promise2 = new Promise((res,rej) => {
  setTimeout(()=>{
    resolve('promise2')
  })
})
Promise.all([promise1,promise2]).then()

Promise.race和Promise.all类似,只不过这个函数会在promise中第一个promise的状态扭转后就开始后面的处理(fulfilled、rejected均可)
配合async await使用:现在的开发中我们大多会用async await语法糖来等待一个promise的执行结果。async本身是一个语法糖,将函数的返回值包在一个promise中返回。

const p=async function f(){
  return '1'
}
p.then((res)=>{
  console.log(res)   //1
})

开发技巧:在前端开发上promise大多被用来请求接口,axios库也是开发中使用最频繁的库,但是频繁的try catch捕捉错误会让代码嵌套很严重。考虑如下代码的优化方式

const getUserInfo=async function(){
  return new Promise((res,rej)=>{
    //resolve()||reject()
  })
}
//为了处理可能的抛错 将try catch套在代码外面
try{
  const user= await getUserInfo()
}catch(err){}
//好的处理方法是在异步函数中将错误catch

async awite的写法在uniapp的文件上传中使用

// 获取上传状态
    async select (res) {
      console.log('选择文件:', res)
      await this.uploadFile(res.tempFilePaths[0]);
    },
    uploadFile (tempFilePaths) {}

使用async关键字可以让函数具有异步特征,但总体上其代码仍然是同步求值的。而再参数或闭包方面,异步函数仍具有普通js函数的正常行为。下面的foo()函数仍然会再后面的指令之前被求值。

async function foo(){
  console.log(1)
}
foo()//1

异步函数如果使用return关键字返回了值(如果没有return则会返回undefined),这个值会被Promise.resolve()包装成一个期约对象。异步函数始终返回期约对象。在函数外部调用这个函数可以得到它返回的期约。

async function foo(){
  console.log(1)
  return 2
} 
//给返回的期约添加一个解决处理程序
foo().then(console.log)
console.log(3)
//1
//3
//2

当然直接返回一个期约对象也是一样的

async function foo(){
  console.log(1)
  return Promise.resolve(3)
}

拒绝期约的错误不会被异步函数捕获

async function foo(){
  Promise.reject(3)//Uncaught (in promise):3
}

因为异步函数主要针对不会马上完成的任务,所以自然需要一种暂停和恢复执行的能力。使用await关键字可以暂停异步函数代码的执行,等待期解决。

let p=new Promise((resolve,reject) => setTimeout(resolve,1000,3))
p.then((X) => console.log(x)); //3

使用async/await可以写成这样

async function foo(){
  let p=new Promise((resolve,reject) => setTimeout(resolve,1000,3))
  console.log(await p)
}
foo()//3

async function bar(){
  return await Promise.resolve('bar')
}
bar().then(console.log)//bar

等待会抛出错误的同步操作,会返回拒绝的期约

async function foo(){
  console.log(1)
  await (() => {throw 3;})
}
//给返回的期约添加一个拒绝处理程序
foo().catch(console.log)//3

单独的Promise.reject()不会被异步函数捕获,而会抛出未捕获错误。不过,对拒绝的期约使用await则会释放(unwrap)错误值(将拒绝期约返回)。

async function foo(){
  console.log(1)
  await Promise.reject(3)
  console.log(4)//这行代码不会执行
}
//给返回的期约添加一个拒绝处理程序
foo().catch(console.log)
console.log(2)
//1
//2
//3

async/await中真正起作用的是await。async关键字,无论从哪方面来看,都不过是一个标识符。异步函数如果不包含await关键字,其执行跟普通函数基本上没有什么区别。
js运行时在碰到await关键字时,会记录在哪里暂停执行。等到await右边的值可用了,js运行时会向消息队列中推送一个任务,这个任务会恢复异步函数的执行。即使await后面跟着一个立即可用的值,函数的其余部分也会被异步求值。
如果await后面是一个期约,则问题会稍微复杂一些。此时,为了执行异步函数,实际上会有两个任务被添加到消息队列并被异步求值。

async function foo(){
  console.log(await Promise.resolve('foo'))
}
async function bar(){
  console.log(await 'bar')
}
async function baz(){
  console.log('baz')
}
foo()
bar()
baz()
//baz 
//bar
//foo

串行执行期约

function addTwo(x){ return x+2 }//或者 async function addTwo
function addThree(x){ return x+3 }
function addFive(x){ return x+5 }

async function addTen(x){
  for(const fn of [addTwo,addThree,addFive]){
    x=await fn(x)
  }
  return x;
}
addTen(9).then(console.log)//19

这里await直接传递了每个函数的返回值,结果通过迭代产生。当然,这个例子并没有使用期约,如果要使用期约,则可以把所有函数都改成异步函数。这样它们就都返回期约了。async function addTwo(x) {return x+2;}

  • 举例
//for循环不影响执行顺序 异步请求需要等待请求结果时影响 但使用方法类似
var sum = 0
    function testAsync() {
      return new Promise((resolve, reject) => {
        for (var i = 0; i < 10; i++) {
          sum += i
        }
        resolve(sum)
      });
    }

     function callerFun() {
      console.log("Caller");
      await testAsync().then((res) => {
        console.log(sum)
      });
      console.log("After waiting");
    }
    callerFun();
//等待请求结果
 async loadData (arg) {
      let data= await this.searchData(arg)
      //findnode需要searchData的请求结果
      await this.findnode(data).then((resolve)=>{
        //获取数据
        this.dataSource=resolve
      })
    },
    searchData (arg) {
     return new Promise ((resolve,reject)=>{
         getAction(this.url.list, params).then((res) => {
          if (res.success) {
            resolve(res.result.records)
          } else {
            reject()
            this.$message.warning(res.message)
          }
        })
     })
    },
    findnode (data) {
      return new Promise((resolve, rej) => {
       data.map((i,index) => {
          let param = {}
          param.id = i.id
          getAction('/jeecg-system/sys/ext/queryByDataId', param).then((res) => {
            console.log(res)
            if (res.code == "200") {
              i.assignee_dictText = res.result.assignee_dictText
              i.nodeName = res.result.nodeName
            }
            //在循环结束后返回结果
            if(index==data.length-1){
              resolve(data)
            }
          })
        })
      })
    },

4、缺少npm环境
在这里插入图片描述
5、
网页弹窗 会在当前浏览器窗口弹出一个新的浏览器窗口(iframe跨域问题不能直接访问某些链接比如百度)

    showModal(location) {
      var wid = 800;
      var hgt = 600;
      var href = api.InforSystem;
      var x = (screen.width - wid) / 2;
      var y = (screen.height - 20 - hgt) / 2;
      var winstyle = 'width=' + wid + ',height=' + hgt + ',left=' + x + ',top=' + y + ',status=no,menubar=no,scrollbars=yes,toolbar=no,resizable=yes';
      lastopenwin = window.open(href + location, '_blank', winstyle, true);
      lastopenwin.focus();
    },

6、import {***} from和 import ** from (带不带大括号的问题)

//1
import { commonMixin } from 
export const commonMixin = {}
//2
import  ReimburseBpmMixin  from 
const ReimburseBpmMixin = {
	data() {
		return {
		}
	},
	methods: {
	}
}
export default ReimburseBpmMixin;

7、uniapp获取不到路由参数时(当然有可能是这个项目有问题)
window.location.href
路由参数乱码时

//如果data是一个对象就JSON.stringify
url: '/pages/12323243?item='+encodeURIComponent(JSON.stringify(data))
let url=window.location.href
let index=url.indexOf("=")
let urldata= url.substring(index+1,url.leng)

8、遍历Object属性
https://segmentfault.com/a/1190000041977281
遍历两个数组寻找一个对象中的key与另一个对象中value匹配的值
在这里插入图片描述

data.map((obj) => {
  Object.keys(obj).forEach(akey => {
    this.columns.map((i) => {
      Object.keys(i).forEach(item => {
        //如果column的align的值==obj里的key 就把 column里的title汉字 在obj里存为汉字
        if (item == 'dataIndex') {
          if (i[item] == akey) {
            debugger
            console.log(i[item] + "------" + akey + "---------" + i.title)
            //wkflwID------wkflwID---------流程定义号
            let key = akey
            let value = i.title 
            this.translate[key] = value
          }
        }
      })
    })
  })
})
//v-for遍历数据要使用translate对象中的key遍历时要写item[xxx] 而不是 item.xxx
  <view class="cu-item"
        v-for="(item,index) in tableData"
        :key="index">
    <view class="content"
          style="left: 24px;">
      <view class="text-grey">
        <span v-for="(a,b) in translate"
              :key="b"
              style="font-size: 13px;">{{a}}{{item[b]}}</span>
      </view>
    </view>
  </view>

9、动态设置style的值

 :style="{'height':`${cardeleH}px`,}"

10、uniapp跳转页面传参
https://www.jianshu.com/p/0f4959df7abb
在这里插入图片描述
11、子组件input通过v-model传值
https://www.jianshu.com/p/854fc40cf0b4
当父组件调用子组件包含的input输入框时 需要将子组件input输入框的值绑定给父组件的v-model 不再需要用$emit向父组件传值

//父组件
  <view class="cu-form-group ">
    <view class="title"><text class="text-red">*</text><text space="ensp">报销科目:</text></view>
    <OnlineSelectTree 
            v-model="model.subject"
            name="input" />
  </view>
//子组件
   <input v-model="selected"
           placeholder="请选择"
           readonly
           disabled="true" />
    <Zpopup :value="openPop"
            @change="onChange"
            :type="'bottom'">
      <view class="pop-box">
        <view class="pop-title">
        </view>
        <view style="overflow: scroll;"
              class="popup_content">
          <LyTree ref="xyTree"
                  :treeData="treeData"
                  @cnecked="treeChecked"></LyTree>
        </view>
      </view>
    </Zpopup>
  methods:{//给子组件的input赋值时给父组件传值
      treeChecked (data) {
      this.selected=data.name
      // this.$emit('treeChecked',data)
       this.$emit('input', this.selected);
      // #ifndef MP-WEIXIN
      this.$emit('change', this.selected);
      // #endif
    },
  },
  model: {//与methods同级
    prop: 'value',
    event: 'input'
  }

12、cascader级联的问题 tree应该也会有同样的问题:children.filter not a function 和 options not array数据不是数组形式就装不进去
13、uniapp的form表单可以验证表单规则
https://uniapp.dcloud.net.cn/component/uniui/uni-forms.html

 <uni-forms ref="form"
                 :model="model"
                 :rules="rules"
                 validate-trigger="bind"
                 err-show-type="undertext">
        <uni-forms-item name="proposer"
                        label="申请人"
                        :required="">
        //不写require就没有必填的星号 rules里写true也不行
          <input v-model="model.proposer"
                 placeholder="请输入"
                 name="proposer" />
        </uni-forms-item>
  </uni-forms>
   rules: {
        age: {
          rules: [{
            required: true,
            errorMessage: '请输入年龄'
          },
          {
            format: 'number',
            errorMessage: '年龄只能输入数字'
          },
          {
            minimum: 1,
            maximum: 200,
            errorMessage: '年龄范围{minimum}~{maximum}'
          },
          ]
        },
      },

14、uniapp给上级页面传递信息 除了$emit之外

//子页面
survyData(data){
      let pages = getCurrentPages()
      let prevPage = pages[pages.length - 2]
      prevPage.$vm.getValue(data, 'survy')
      this.close();
},
//父页面
getValue (data, type) {}

15、在循环结束后根据循环的结果进行处理 async await promise

  async submit () {
      let status = await this.checkTable()
      this.$refs['form'].validate()
        .then(result => {
          console.log("验证通过", result);
          if (status == true) {
            this.submitForm()
          }
        })
        .catch(errors => {
          this.$tip.toast('信息未填写完整,请检查!');
          console.log("验证不通过=>", errors);
          return
        })
    },
    checkTable () {
      return new Promise((resolve, reject) => {
        this.$store.state.operateList.map((i) => {
          if (i.subject == undefined || i.subject == null) {
            this.$tip.toast('报销明细(票夹信息)信息未填写完整,请编辑!');
            resolve(false)
            return
          }
        })
        resolve(true)
      })
    },

另一种 文件上传时

  // 获取上传状态
    async select (res) {
      console.log(this.attachment)
      console.log('选择文件:', res)
      await this.uploadFile(res.tempFilePaths[0]);
    },
    uploadFile (tempFilePaths) {}

16、uniapp返回上一级是重载上一级的表单
如果不是foot页 可以使用

let pages = getCurrentPages();
let prevPage = pages[ pages.length - 2 ];//上一页
console.log("prevPage===>",prevPage)
prevPage.$vm.downCallback()//调用上一页的方法
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值