react this.setState接收参数 。写成Promise形式。以及async/await和Promise的区别

同步编程通常来说易于调试和维护,然而,异步编程通常能获得更好的性能和更大的灵活性异步的最大特点是无需等待。“Promises”渐渐成为JavaScript里最重要的一部分,大量的新API都开始promise原理实现。

Promise基本用法

new Promise()构造器可以用在传统的异步任务中,就像以前 setTimeout 和 XMLHttpRequest 的用法一样。一个新的 Promise 使用 new 关键字生成,同时,这个 Promises 提供了 resolve 和 reject 函数让我们执行回调操作:(写一个模板示例)
在这里插入图片描述

      let p = new Promise(function(resolve, reject){
        if('条件'){
          resolve('成功')
        }else{
          reject('失败')
        }
      })
      p.then(function(){})
      .catch(function(){})

Promise.resolve() 和 Promise.reject() 可以直接被调用。
有时候,当判断出 promise 并不需要真正执行时,我们并不需要 使用 new 创建 Promise 对象,而是可以直接调用 Promise.resolve() 和 Promise.reject()。
因为 promise 肯定会返回,所以,我们可以使用 then 和 catch 方法处理返回值!
我们在写一个优化的示例

假设我们写个 函数请求:
 function request(url, callback) {
    setTimeout(() => {
      callback({
        code: 0,
        data: "成功了",
      });
    }, 2000);
  }

然后对其进行优化处理 此时用到了 async/await 。

async/await

async/await是写异步代码的新方式,它是generator的语法糖,以前的方法有回调函数和 Promise。async/await是基于Promise实现的,它不能用于普通的回调函数。
**async/await与Promise一样,是非阻塞的。async/await使得异步代码看起来像同步代码,**这正是它的魔力所在。

在这里插入图片描述

在这里插入图片描述
上图你可以看到
async function test2() {
const res = await request1(“/api/list”, 0); // 初始参数为0 两秒后加1 ,打印结果为1,2,3
console.log(res);
const res1 = await request1(“/api/list1”, res.code);
console.log(res1);
const res2 = await request1(“/api/list1”, res1.code);
console.log(res2);
}
在这里插入图片描述

function request(url, callback) {
        setTimeout(() => {
          callback({
            code: 0,
            data: "成功了",
          });
        }, 2000);
      }
这两个其实一样,但是下者更为优化处理。
function request1(url, code) {
        return new Promise((resolve) => {
          setTimeout(() => {
            resolve({
              code: code + 1,
              data: "成功了",
            });
          }, 2000);
        });
      }

项目中我们会尝尝用到 异步请求 async await 以及promise 。
当我点击了购车购物车按钮后在购物车页面。但是发现又问题看代码
在这里插入图片描述

在这里插入图片描述
原本别人写的(react项目)

//购物车数量调整
  modifyQty = async (e, record, v) => {
    const { dataSource } = this.props;
    let packNum = v;
    switch (e) {
      case 'add':
        packNum += 1;
        break;
      case 'minus':
        if (packNum > 1) {
          packNum -= 1;
          break;
        }
        return;
      case 'change':
        if (record.packNum === v) return;
    }
    this.props.setState({shopLoading: true}, async () => {
        const res = await modifyQty({
          id: record?.id,
          moq: record?.moq,
          packNum,
          unit: record?.unit
          // packNum: record?.packNum
        });
        if (res.success) {
          this.props.setState({
            shopLoading: false,
            dataSource: dataSource.map((item) => {
              return {
                ...item,
                cartList: item?.cartList.map((v) => {
                  if (record.id === v?.id) {
                    return {
                      ...v,
                      packNum
                    };
                  }
                  return v;
                })
              };
            })
          });
        } else {
          this.props.setState({ shopLoading: false });
          ElNotification({ type: 'error', message: res.msg || res.errorMsg });
        }
      }
    );

后来我改动的

this.props.setState( { shopLoading: true },  async () => {
  const res = await modifyQty({
   id: record?.id,
   moq: record?.moq,
   packNum,
   unit: record?.unit
 });
 if (res.success) {
   this.props.setState(
   {
	   shopLoading: false,
       dataSource: dataSource.map((item) => {
       return {
 		...item,
	     cartList: item?.cartList.map((v) => {
	     if (record.id === v?.id) {
	        return {
		     	...v,
		       packNum
		        };
		      }
	       return v;
		  })
      };
    })
},
//    计算总和显示在购物车图标上
 const total = this.props.dataSource.reduce((total, cur) => {
     return (
      total +  cur.cartList.reduce((tempTotal, cur) => {
         return tempTotal + cur.packNum;
        }, 0)
      );
     }, 0);
    
    //或者用forEach 写循环
	 // let total = 0;
      // this.props.dataSource.forEach((cur) => {
    //   let tempTotal = 0;
    //   cur.cartList.forEach((cur) => {
     //     tempTotal = tempTotal + cur.packNum;
       //   });
       //   total = total + tempTotal;
       // }, 0);
 		console.log(total);
	     }
     );
   } else {
    this.props.setState({ shopLoading: false });
     ElNotification({ type: 'error', message: res.msg || res.errorMsg });
    }
   }
);

之所以写了双循环是因为接口返回是两层,一般是一层就可以了。
在这里插入图片描述
但是发现代码还可以优化
写成 Promise的形式。

写一个方法
  propsSetStateAsync(data) {
    return new Promise((resolve) => {
      this.props.setState(data, () => {
        resolve(undefined);
      });
    });
  }
  //购物车数量调整
  modifyQty = async (e, record, v) => {
    const { dataSource } = this.props;
    let packNum = v;
    switch (e) {
      case 'add':
        packNum += 1;
        break;
      case 'minus':
        if (packNum > 1) {
          packNum -= 1;
          break;
        }
        return;
      case 'change':
        if (record.packNum === v) return;
    }
    await this.propsSetStateAsync({  shopLoading: true  });
    const res = await modifyQty({
      id: record?.id,
      moq: record?.moq,
      packNum,
      unit: record?.unit
      // packNum: record?.packNum
    });
    这里逻辑是每点击加减都要请求接口,虽然扯淡,但是按照需求做吧,所以我是在请求接口后计算的。
    if (res.success) {
      await this.propsSetStateAsync({
        shopLoading: false,
        dataSource: dataSource.map((item) => {
          return {
            ...item,
            cartList: item?.cartList.map((v) => {
              if (record.id === v?.id) {
                return {
                  ...v,
                  packNum
                };
              }
              return v;
            })
          };
        })
      });
      计算总和回赋值到购物车图表上
      const total = this.props.dataSource.reduce((total, cur) => {
        return (
          total +
          cur.cartList.reduce((tempTotal, cur) => {
            return tempTotal + cur.packNum;
          }, 0)
        );
      }, 0);
      console.log(total); 拿到这个值,
      // 计算拿到总数后,应该请求购物车接口改变数量
 	 // 这里写购物车接口并刷新数据,但是目前还没有接口就空着了
    } else {
      this.props.setState({ shopLoading: false });
      ElNotification({ type: 'error', message: res.msg || res.errorMsg });
    }
  };

使用过React的应该都知道,在React中,一个组件中要读取当前状态需要访问this.state,但是更新状态却需要使用this.setState,不是直接在this.state上修改。
setState(updater, callback)这个方法是用来告诉react组件数据有更新,有可能需要重新渲染。
生命周期中,setState是“异步”的 。
看到了一个不错的文章分享给你 了 看看这个介绍对我们有好处

猜你喜欢

转载自blog.csdn.net/lzfengquan/article/details/126027096
今日推荐