• 有趣的async


    在项目的开发过程中,同步异步是一个很重要的概念。但是在js中,又会有稍微的不同。
    依据微软的MSDN上的解说:
    (1) 同步函数:当一个函数是同步执行时,那么当该函数被调用时不会立即返回,直到该函数所要做的事情全都做完了才返回。
    (2) 异步函数:如果一个异步函数被调用时,该函数会立即返回尽管该函数规定的操作任务还没有完成。
    我们从效率上进行比较同步函数与异步函数,我们可以发现,同步函数是一个完成了再执行下一个,而异步函数是调用就返回。
    自然是同步函数效率更低,但是相比于,异步函数的不可靠,不等被调方返回结果就转身离去,同步函数至少在执行力上强于异步函数。
    由于异步调用容易出问题,要设计一个安全高效的编程方案需要比较多的设计经验,所以最好不要滥用异步调用。同步调用毕竟让人更舒服些:不管程序走到哪里,只要死盯着移动点就能心中有数,不至于象异步调用那样,总有一种四面受敌、惶惶不安的感觉。必要时甚至可以把异步函数转换为同步函数。方法很简单:调用异步函数后马上调用 wait 函数等在那里,待异步函数返回结果后再继续往下走。
    假如回调函数中包含文件处理之类的低速处理,调用方等不得,需要把同步调用改为异步调用,去启动一个单独的线程,然后马上执行后续代码,其余的事让线程慢慢去做。一个替代办法是借 API 函数 PostMessage 发送一个异步消息,然后立即执行后续代码。这要比自己搞个线程省事许多,而且更安全。
    现在出现了我们的async异步函数,我们来看看它是如何保证了异步函数的准确运行
    async 函数是什么?一句话,它就是 Generator 函数的语法糖。
    那什么是Generator 函数呢?
    我们先来看一个例子

    function* helloWorldGenerator(){
      yield 'hello';
      yield 'world';
      return 'ending'
    }
    var hw=helloWorldGenerator();
    hw.next()
    // { value: 'hello', done: false }
    //又或者
    hw.next()
    // { value: 'world', done: false }
    
    hw.next()
    // { value: 'ending', done: true }
    
    hw.next()
    // { value: undefined, done: true }
    

    总结一下就是调用 Generator 函数,返回一个遍历器对象,代表 Generator 函数的内部指针。以后,每次调用遍历器对象的next方法,
    就会返回一个有着value和done两个属性的对象。value属性表示当前的内部状态的值,是yield表达式后面那个表达式的值;done属性是一个布尔值,
    表示是否遍历结束。
    下文是有一个 Generator 函数,依次读取两个文件。

    const fs = require('fs');
    
    const readFile = function (fileName) {
      return new Promise(function (resolve, reject) {
        fs.readFile(fileName, function(error, data) {
          if (error) return reject(error);
          resolve(data);
        });
      });
    };
    
    const gen = function* () {
      const f1 = yield readFile('/etc/fstab');
      const f2 = yield readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };
    
    

    上面代码的函数gen可以写成async函数,就是下面这样。

    const asyncReadFile = async function () {
      const f1 = await readFile('/etc/fstab');
      const f2 = await readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };
    
    

    阮一峰的es6上说
    一比较就会发现,async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。
    其实我写本文的最终目的就是来自一句话,一句话顿悟了我,其实很简单的一句话

    async异步函数,加了await就是把函数变成同步。(函数既然同步了,那就是按照循序执行,方便使用,方便查看顺序。)

    关于使用async异步函数封装react组件的方法

    import React,{Component} from 'react'
    import './NewComponent.less'
    import { List, Avatar,Modal} from 'antd';
    const prefix="liu-chang-c-new-Component";
    
    class NewComponent extends Component{
    
      state = {
        ComponentList: [],
      }
    
      componentDidMount() {
        this.queryComponent();
      }
    
      queryComponent = async () => {
        const ComponentList = [];
        for (let i = 0; i < 10; i++) {
          ComponentList.push({
            href: 'http://ant.design',
            title: `ynne Lan${i}`,
            avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
            description: 'edit',
            content: ' Device Group Name: 001Device Group: 001',
            time:'Today 19:16'
          });
        }
    
        this.setState({ComponentList});
      }
    
      showComponentInfo = (data) => {
        Modal.info({
          title: 'This is a notification message',
          content: (
            <div>
              <p>{data.title}</p>
              <p>{data.time}</p>
              <p>{data.description}</p>
              <p>{data.content}</p>
            </div>
          ),
          onOk() {},
          okText: 'Close',
        });
      }
    
      render() {
        const { ComponentList } = this.state;
        return (
          <div className={prefix} >
            <List
              className={`${prefix}-list`}
              itemLayout="vertical"
              size="large"
              
              pagination={{
                onChange: (page) => {
                  console.Component(page);
                },
                pageSize: 3,
              }}
              dataSource={ComponentList}
              renderItem={item => (
                <List.Item
                  key={item.title}
                  extra={item.time}
                  className={`${prefix}-item`}
                  onClick={() => this.showComponentInfo(item)}
                >
                <List.Item.Meta
                className={`${prefix}-meta`}
                  avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
                  title={<a href={item.href}>{item.title}</a>}
                  description={item.description}
                />
                {item.content}
    
                </List.Item>
              )}
            />
          </div>
        )
      }
    }
    
    export default NewComponent;
    

    本文参考文章
    http://es6.ruanyifeng.com/#docs/async
    https://www.cnblogs.com/balingybj/p/4780442.html

  • 相关阅读:
    Pandas也能轻松绘图,简单而又漂亮
    笔试题: 二叉排序数左移k个
    补题next_permutation
    从HTTP到HTTPS
    HTTP首部字段详解
    HTTP请求方法及响应状态码详解
    HTTP报文格式详解
    TCP/IP网络基础
    Netty学习笔记
    ZooKeeper学习笔记
  • 原文地址:https://www.cnblogs.com/smart-girl/p/10167795.html
Copyright © 2020-2023  润新知