js高级进阶:promise同步编程技巧

promise是ES6引进的异步编程解决方案,是一个构造函数,可以实例化对象,可以解决回调地狱的问题。
首先我们看一下promise的实例化对象是什么:

 let P = new Promise(function(){});//new一个promise传入一个函数
 console.log(P);

打印结果:js高级进阶:promise同步编程技巧_第1张图片可以看到promise是一个对象 有自己的原型,有then,catch等方法

promise的参数
promise的参数是一个函数 这个函数有两个参数 分别是reject(失败的回调)和resolve(成功的回调)。
resolve的用法:

    let P = new Promise(function(resolve ,reject ){
      /*函数体执行完之后调用resolve*/
      resolve('成功')
    });
    P.then((res)=>{
      console.log(res);
    })

打印结果:
在这里插入图片描述
在函数体执行完之后调用resolve(),结果会走then()方法

reject的用法

    let P = new Promise(function(resolve ,reject ){
      /*还是执行完之后调用reject*/
      reject('错误')
    });
    P.catch(function(err){
      console.log(err);
    })

打印结果:
在这里插入图片描述
在函数体执行完之后调用reject(),结果会走catch()方法

promise的then方法使用:

浏览器编译遇见then()方法调用promise实例,并在函数调用resolve()之后编译then()中的函数体

    var num = 1;
    let P = new Promise(function (resolve, reject) {
      setTimeout(function () {
        num = 2;
        resolve();
      }, 2000);
    });
    P.then(function (res) {
      console.log(num); // 浏览器编译遇见then()方法会走promise函数体 在函数体调用resolve()之后再编译then()的函数体 两秒之后num重新赋值为2 此时为2
    });
    console.log(num); // 直接打印num 此时为1

promise的catch方法使用:

用法和then()一样
在浏览器编译遇到reject()时调用。

promise的all方法使用:

    let P = new Promise(function (resolve, reject) {
      setTimeout(function () {
        resolve();
      }, 2000);
    });

    let P2 = new Promise(function (resolve, reject) {
      setTimeout(function () {
        resolve();
      }, 5000);
    });
    Promise.all([P, P2]).then(function () {
      alert(111);// 5秒之后弹出 
    });

all()方法传入一个数组,这个数组的元素是多个promise实例,在所有实例执行完之后执行then()方法。 

 

工作中遇到的问题:多个请求同步执行

 比如我有一个上传文件的需求,但是,每次只能上传一个文件,而且只能同步执行上传请求,不能一下全都发送过去,所以就需要使用同步执行多个上传请求:需要配合for循环和promise一起使用,for循环多个文件,await 一个promise请求,当promise执行完之后,再循环下一次:

const startUpFiles = async () => {
  console.log("开始多文件上传", fileList);
  for (let index = 0; index < fileList.length; index++) {
    const uploadFile = fileList[index];
    // console.log("file---", element.name);
    await new Promise((resolve, reject) => {
      // 当前日期
      var date = new Date()
      var reader = new FileReader()
      var uploadType = getType(uploadFile.raw.type, uploadFile)
      reader.readAsDataURL(uploadFile.raw)
      reader.onload = function (event: any) {
        // 用于预览图片
        var uploadFileRaw = reactive({
          name: uploadFile.name,
          path: uploadType === 'picture' ? event!.target.result : "",
          type: uploadType,
          size: (uploadFile.size / 1024 / 1024).toFixed(2).toString() + "M",
          sha: "",
          openLink: 'https://element-plus.gitee.io/',
          downLink: 'https://element-plus.gitee.io/',
          htmlLink: '',
          creatTime: `${date.getFullYear()}-${date.getMonth() + 1
            }-${date.getDate()}`,
          selected: false,
          showTips: false,
          uploading: true,
        })
        gitFileList.push(uploadFileRaw)
        // 用于上传图片
        fileApi.uploadFile(`${filePath.value}/${uploadFile.name}`, {
          "message": "Upload From FileHub",
          "content": event!.target.result.split("base64,")[1]
        }).then((res: any) => {
          console.log("上传文件返回:", res);
          if (res.status === 201) {
            uploadFileRaw.uploading = false
            uploadFileRaw.path = res.data.content.path
            uploadFileRaw.sha = res.data.content.sha
            uploadFileRaw.openLink = uploadType === 'picture' ? `${uStore.fileCdn}${res.data.content.path}` : `${uStore.gitIoCdn}/${res.data.content.path}`
            uploadFileRaw.downLink = uploadType === 'picture' ? `${uStore.fileCdn}${res.data.content.path}` : `${uStore.gitIoCdn}/${res.data.content.path}`
            uploadType === 'picture' && imgPreList.push(`${uStore.fileCdn}${res.data.content.path}`)
            console.log("上传文件结果:", res, imgPreList)
            resolve("200")
            upPropress.value = index + 1
          } else {
            ElMessage.error("上传失败:" + res.data.message)
            gitFileList.splice(gitFileList.indexOf(uploadFileRaw), 1)
            reject("409")
            upPropress.value = index + 1
          }
        }).catch(error => {
          uploadFileRaw.sha = 'error'
          gitFileList.splice(gitFileList.indexOf(uploadFileRaw), 1)
          console.log("上传文件错误:", error);
          reject("409")
          upPropress.value = index + 1
        })
      }
    })
  }
}

但是这个请求之前,需要先拿到上传的多个文件列表:做一个防抖延时拿到所有的上传文件

// 上传文件回调事件
const handleUploadChange = (uploadFile: any, uploadFiles: any) => {
  console.log('handleUploadChange----', uploadFiles, fileList)
  fileList = uploadFiles
  upTimer && clearTimeout(upTimer)
  upTimer = setTimeout(() => {
    upTimer = null
    console.log('防抖 高频触发后n秒内只会执行一次  再次触发重新计时')
    startUpFiles() //说明此时change了所有文件了 可以上传了
  }, 1000)
  console.log('gitFileList-----', gitFileList)
}

你可能感兴趣的:(HTML前端,javascript,前端,开发语言)