function 订阅
Function,表示子例程的一般性名词。在某些编程语言中,它指带返回值的子例程或语句。在一些编程语言中起着关键字的作用。在Python中,function是非常重要而且常见的,一般获取类或函数的参数信息。 展开全文
Function,表示子例程的一般性名词。在某些编程语言中,它指带返回值的子例程或语句。在一些编程语言中起着关键字的作用。在Python中,function是非常重要而且常见的,一般获取类或函数的参数信息。
信息
属    性
一般性名词
应用领域
编程
中文名
Function
实    质
带返回值的子例程或语句
Function分类
在Python中,function一般有如下几类:一、POSITIONAL_OR_KEYWORD如果没有任何*的声明,那么就是POSITIONAL_OR_KEYWORD类型的,如同语义一样,POSITIONAL_OR_KEYWORD类型的参数可以通过位置POSITIONAL传参调用,也可以过关键字KEYWORD传参。以下是一个最简单的例子:def foo(a):pass# 位置传参调用foo(1)# 关键字传参调用foo(a=1)二、VAR_POSITIONAL第二种是可变的位置参数,通过一个*前缀来声明,如果你看到一个*xxx的函数参数声明(不是函数调用!声明和调用是两种不同的含义的),那一定是属于VAR_POSITIONAL类型的,如同语义,这种类型的参数只能通过位置POSITIONAL传参调用,不支持关键字KEYWORD传参,在函数内部,VAR_POSITIONAL类型的参数以一个元祖(tuple)显示,有一点需要注意的,VAR_POSITIONAL类型可以不传任何参数调用也不会报错,而且只允许存在一个。以下是一个简单的例子:def foo(*b):print(b)# 不传参数不会报错,参数值是一个空元祖foo() # 结果是 ()# 可以传入任意个位置参数调用foo(1, 2.0, '3', True) #结果是 (1, 2.0, '3', True)三、KEYWORD_ONLY第三种是关键字参数,这种参数只会在VAR_POSITIONAL类型参数的后面而且不带**前缀。如同语义,这类参数只能用关键字KEYWORD来传参,不可以用位置传参,因为位置传的参数全让前面的VAR_POSITIONAL类型参数接收完了,所以KEYWORD_ONLY只能通过关键字才能接收到参数值。以下是一个简单的例子:# VAR_POSITIONAL不需要使用时,可以匿名化def foo(*, c):pass# 只能关键字传参调用foo(c=1)四、VAR_KEYWORD第四种是可变的关键字参数,VAR_KEYWORD类型的参数通过**前缀来声明(不是函数调用!声明和调用是两种不同的含义的)。如同语义,这种类型的参数只能通过关键字KEYWORD调用,但可以接收任意个关键字参数,甚至是0个参数,在函数内部以一个字典(dict)显示。VAR_KEYWORD类型的参数只允许有一个,只允许在函数的最后声名。以下是简单的例子:def foo(**d):print(d)# 不传参数不会报错,参数值是一个空字典foo() # 结果是 {}# 可以传入任意个关键字参数调用foo(a=1, b=2.0, c='3', d=True) # 结果是 {'d': True, 'c': '3', 'b': 2.0, 'a': 1}五、POSITIONAL_ONLY第五种是位置参数,选择最后说这个,是因为它一点也不重要,属于python的历史产物,你无法在高版本的python中创建一个POSITIONAL_ONLY类型的参数,在某种底层的内置函数也许会使用这类型的参数,但我试用inspect模块也没法正确识别它的命名,但在Ipython的??帮助下,还是能看到Init signature: dict(self, /, *args, **kwargs)这里的self就是位置参数POSITIONAL_ONLY了。相信我,你不会需要用到它的,python推荐用VAR_POSITIONAL来代替它。下面是一个综合示例:import inspectdef foo(a, *b, c, **d):passfor name, parame in inspect.signature(foo).parameters.items():print(name, ': ', parame.kind)默认参数VAR类型不允许设置默认参数POSITIONAL_OR_KEYWORD和KEYWORD_ONLY可以自定义默认参数,而VAR_POSITIONAL和VAR_KEYWORD不允许自定义默认参数的,因为VAR_POSITIONAL的默认参数是tuple()空元祖,而VAR_KEYWORD的默认参数是dict()空字典。如果自定义了默认参数的话,调用函数的时候可以不必传参,如果默认值是空的话,那就必须传参数才能调用。默认参数的位置POSITIONAL_OR_KEYWORD类型的默认参数一定要放在后面,否则会报错,KEYWORD_ONLY虽然没有强制要求,因为都是用关键字传参,谁先谁后都无所谓,但最好还是尽可能地放在后面吧。默认参数不默认?默认参数绝对不能设置为可变类型(比如list, dict, set),如果你在函数内改变了默认参数,下次再调用时它就不再是默认值了。正确的示例:def foo(p1, p2=2.0, *, k1, k2=None):a_list = k2 or list()passfoo(1, k1='3')
收起全文
精华内容
下载资源
问答
  • 2019-09-16 14:14:12

    笔者日常 来吧,Function~


    相关声明

    • 本文按照以下顺序进行说明并给出简单的使用示例:

      序号接口
      1Function<T, R>
      2IntFunction<R>
      3DoubleFunction<R>
      4LongFunction<R>
      5ToIntFunction<T>
      6ToLongFunction<T>
      7ToDoubleFunction<T>
      8IntToDoubleFunction
      9IntToLongFunction
      10LongToDoubleFunction
      11LongToIntFunction
      12DoubleToIntFunction
      13DoubleToLongFunction
      14BiFunction<T, U, R>
      15ToIntBiFunction<T, U>
      16ToLongBiFunction<T, U>
      17ToDoubleBiFunction<T, U>
    • 先给出下文的示例中所涉及到的模型:

      /**
       * 员工实体模型
       *
       * @author JustryDeng
       * @date 2019/7/15 19:48
       */
      @Data
      @AllArgsConstructor
      @NoArgsConstructor
      @Builder
      public class Staff implements Serializable {
      
          /** 姓名 */
          private String name;
      
          /** 年龄 */
          private Integer age;
      
          /** 工号 */
          private String staffNo;
      
      }
      

    Function<T, R>

    • R apply(T t) 输入T类型的参数,运行相关逻辑后,返回R类型的结果。
      使用示例:

      /**
       *  R apply(T t): 输入T类型的参数,运行相关逻辑后,返回R类型的结果。
       */
      @Test
      public void test1() {
          Function<String, Staff> function = x -> {
              Staff s = new Staff();
              s.setName(x + ", 咿呀咿呀哟!");
              return s;
          };
      
          Staff staff = function.apply("邓某");
          // 输出: 邓某, 咿呀咿呀哟!
          System.out.println(staff.getName());
      }
      
    • Function<V, R> compose(Function<? super V, ? extends T> before) 由两个旧的Function得到一个新的Function。

      假设: 现有式子functionC = functionB.compose(functionA),functionA 泛型为<P1, R1>, functionB泛型为<R1, R2>。

      那么, 上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, R2>的functionC<P1, R2>。

      使用示例:

       /**
        * <V> Function<V, R> compose(Function<? super V, ? extends T> before):由两个旧的Function得到一个新的Function。
        *
        * 假设:现有式子functionC = functionB.compose(functionA),
        *      functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。
        *
        * 那么,上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值
        *                     作为functionB<R1, R2>的apply方法的入参,执行
        *                     functionB<R1, R2>的apply方法,返回一个泛型为
        *                     <P1, R2>的functionC<P1, R2>。
        */
       @Test
       public void test2() {
       
           Function<String, Integer> functionA = x -> {
               Objects.requireNonNull(x, "参数不能为空");
               x = x.replace(" ", "");
               return x.length();
           };
       
           Function<Integer, Staff> functionB = x -> {
               Objects.requireNonNull(x, "参数不能为空");
               Staff s = new Staff();
               s.setAge(x);
               return s;
           };
       
           Function<String, Staff> functionC = functionB.compose(functionA);
           Staff staff = functionC.apply(" 我 是 参 数 ! ");
           // 输出: Staff(name=null, age=5, staffNo=null)
           System.out.println(staff);
       }
      
    • Function<T, V> andThen(Function<? super R, ? extends V> after 由两个旧的Function得到一个新的Function。
      假设: 现有式子functionC = functionA.andThen(functionB),functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。
      那么, 上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, R2>的functionC<P1, R2>。
      注: functionA.andThen(functionB)是先执行functionA,再执行functionB;而functionA.compose(functionB)是先执行functionB,再执行functionA。
      使用示例:

       /**
        * <V> Function<T, V> andThen(Function<? super R, ? extends V> after):由两个旧的Function得到一个新的Function。
        *
        * 假设:现有式子functionC = functionA.andThen(functionB),
        *      functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。
        *
        * 那么,上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值
        *                     作为functionB<R1, R2>的apply方法的入参,执行
        *                     functionB<R1, R2>的apply方法,返回一个泛型为
        *                     <P1, R2>的functionC<P1, R2>。
        *
        * 注: functionA.andThen(functionB)是先执行functionA,再执行functionB;
        *     而functionA.compose(functionB)是先执行functionB,再执行functionA。
        */
       @Test
       public void test3() {
       
           Function<String, Integer> functionA = x -> {
               Objects.requireNonNull(x, "参数不能为空");
               x = x.replace(" ", "");
               return x.length();
           };
       
           Function<Integer, Staff> functionB = x -> {
               Objects.requireNonNull(x, "参数不能为空");
               Staff s = new Staff();
               s.setAge(x);
               return s;
           };
       
           Function<String, Staff> functionC = functionA.andThen(functionB);
           Staff staff = functionC.apply(" 我 是 参 数 ! ");
           // 输出: Staff(name=null, age=5, staffNo=null)
           System.out.println(staff);
       }
      
    • static Function<T, T> identity() 将输入的参数进行返回,即: return t -> t。
      注: 在某些情景下,使用Function.identity(),会让代码更优雅。
      使用示例:

       /**
        * static <T> Function<T, T> identity(): 将输入的参数进行返回,即: return t -> t。
        *
        * 说明: 在某些情景下,使用Function.identity(),会让代码更优雅。
        */
       @Test
       public void test4() {
           /*
            * 使用普通的lambda表达式
            */
           Map<Integer, String> mapOne = Stream.of("a", "ab", "abc", "abcd", "abcde").collect(
                   Collectors.toMap(String::length, param -> param)
           );
           // 输出: {1=a, 2=ab, 3=abc, 4=abcd, 5=abcde}
           System.out.println(mapOne);
       
           /*
            * 使用Function.identity()无疑更优雅
            */
           Map<Integer, String> mapTwo = Stream.of("a", "ab", "abc", "abcd", "abcde").collect(
                   Collectors.toMap(String::length, Function.identity())
           );
           // 输出: {1=a, 2=ab, 3=abc, 4=abcd, 5=abcde}
           System.out.println(mapTwo);
       }
      

    IntFunction<R>

    • R apply(int value) 入参类型必须为int, (运行相关逻辑后)返回R类型的数据。
      使用示例:
       /**
        * R apply(int value): 入参类型必须为int, (运行相关逻辑后)返回R类型的数据。
        */
       @Test
       public void test5() {
           IntFunction<Staff> intFunction = x -> {
               Staff staff = new Staff();
               staff.setAge(x);
               return staff;
           };
       
           Staff res = intFunction.apply(100);
           // 输出: Staff(name=null, age=100, staffNo=null)
           System.out.println(res);
       }
      

    DoubleFunction<R>

    • R apply(double value) 入参类型必须为double,(运行相关逻辑后)返回R类型的数据。
      使用示例:
       /**
        * R apply(double value): 入参类型必须为double, (运行相关逻辑后)返回R类型的数据
        */
       @Test
       public void test6() {
           DoubleFunction<String> doubleFunction = x -> (x + "").replace(".", "_");
           String res = doubleFunction.apply(10.01);
           // 输出: 10_01
           System.out.println(res);
       }
      

    LongFunction<R>

    • R apply(long value) 入参类型必须为long, (运行相关逻辑后)返回R类型的数据。

      使用示例:

       /**
        * R apply(long value): 入参类型必须为long, (运行相关逻辑后)返回R类型的数据。
        */
       @Test
       public void test7() {
           LongFunction<String> longFunction = x -> (x + "").replace("4", "  8484884  ").trim();
           String res = longFunction.apply(484);
           // 输出: 8484884  8  8484884
           System.out.println(res);
       }
      

    ToIntFunction<T>

    • int applyAsInt(T value) 入参类型为T,(运行相关逻辑后)返回类型必为int。
      使用示例:
       /**
        * int applyAsInt(T value): 入参类型为T, (运行相关逻辑后)返回类型必为int。
        */
       @Test
       public void test8() {
           ToIntFunction<String> toIntFunction = x -> x == null ? 0 : x.length();
           int res = toIntFunction.applyAsInt("蚂蚁呀~嘿!嘿!");
           // 输出: 8
           System.out.println(res);
       }
      

    ToLongFunction<T>

    • long applyAsLong(T value) 入参类型为T, (运行相关逻辑后)返回类型必为long。
      使用示例:
       /**
        * long applyAsLong(T value): 入参类型为T, (运行相关逻辑后)返回类型必为long。
        */
       @Test
       public void test9() {
           ToLongFunction<String> toLongFunction = x -> x == null ? 0 : new SecureRandom(x.getBytes()).nextLong();
           long res = toLongFunction.applyAsLong("蚂蚁呀~嘿!嘿!");
           // 输出: 2677168598702751372
           System.out.println(res);
       }
      

    ToDoubleFunction<T>

    • double applyAsDouble(T value) 入参类型为T,(运行相关逻辑后)返回类型必为double。
      使用示例:
       /**
        * double applyAsDouble(T value): 入参类型为T, (运行相关逻辑后)返回类型必为double。
        */
       @Test
       public void test10() {
           ToDoubleFunction<Float> toDoubleFunction = x -> x == null ? 0.0 : x;
           double res = toDoubleFunction.applyAsDouble(123.4F);
           // 输出: 123.4000015258789 (注:精度问题不在本文的讨论范围内)
           System.out.println(res);
       }
      

    IntToDoubleFunction

    • double applyAsDouble(int value) 入参类型必须为int,(运行相关逻辑后)返回类型必为double。
      使用示例:
       /**
        * double applyAsDouble(int value): 入参类型必须为int, (运行相关逻辑后)返回类型必为double。
        */
       @Test
       public void test11() {
           IntToDoubleFunction intToDoubleFunction = x -> x + 88.8;
           double res = intToDoubleFunction.applyAsDouble(12300);
           // 输出: 12388.8
           System.out.println(res);
       }
      

    IntToLongFunction

    • long applyAsLong(int value) 入参类型必须为int,(运行相关逻辑后)返回类型必为long。
      使用示例:
       /**
        * long applyAsLong(int value): 入参类型必须为int, (运行相关逻辑后)返回类型必为long。
        */
       @Test
       public void test12() {
           IntToLongFunction intToLongFunction = x -> x + 1000L;
           long res = intToLongFunction.applyAsLong(12345);
           // 输出: 13345
           System.out.println(res);
       }
      

    LongToDoubleFunction

    • double applyAsDouble(long value) 入参类型必须为long, (运行相关逻辑后)返回类型必为double。
      使用示例:
       /**
        * double applyAsDouble(long value): 入参类型必须为long, (运行相关逻辑后)返回类型必为double。
        */
       @Test
       public void test13() {
           LongToDoubleFunction longToDoubleFunction = x -> x + 1000000D;
           double res = longToDoubleFunction.applyAsDouble(12345L);
           // 输出: 1012345.0
           System.out.println(res);
       }
      

    LongToIntFunction

    • int applyAsInt(long value) 入参类型必须为long,(运行相关逻辑后)返回类型必为int。
      使用示例:
       /**
        * int applyAsInt(long value): 入参类型必须为long, (运行相关逻辑后)返回类型必为int。
        */
       @Test
       public void test14() {
           LongToIntFunction longToIntFunction = x -> (int)(x / 1000);
           int res = longToIntFunction.applyAsInt(12345L);
           // 输出: 12
           System.out.println(res);
       }
      

    DoubleToIntFunction

    • int applyAsInt(double value) 入参类型必须为double,(运行相关逻辑后)返回类型必为int。
      使用示例:
       /**
        * int applyAsInt(double value): 入参类型必须为double, (运行相关逻辑后)返回类型必为int。
        */
       @Test
       public void test15() {
           DoubleToIntFunction doubleToIntFunction = x -> (int)x;
           int res = doubleToIntFunction.applyAsInt(123.45);
           // 输出: 123
           System.out.println(res);
       }
      

    DoubleToLongFunction

    • long applyAsLong(double value) 入参类型必须为double,(运行相关逻辑后)返回类型必为long。
      使用示例:
       /**
        * long applyAsLong(double value): 入参类型必须为double, (运行相关逻辑后)返回类型必为long。
        */
       @Test
       public void test16() {
           DoubleToLongFunction doubleToLongFunction = x -> (long)x;
           long res = doubleToLongFunction.applyAsLong(112233.4455);
           // 输出: 112233
           System.out.println(res);
       }
      

    BiFunction<T, U, R>

    • R apply(T t, U u) 输入T类型、U类型的参数,运行相关逻辑后,返回R类型的结果。
      使用示例:

       /**
        *  R apply(T t, U u): 输入T类型、U类型的参数,运行相关逻辑后,返回R类型的结果。
        */
       @Test
       public void test17() {
           BiFunction<Integer, String, Staff> biFunction = (x, y) -> {
               Staff s = new Staff();
               s.setAge(x);
               s.setName(y);
               return s;
           };
       
           Staff staff = biFunction.apply(25, "单身邓");
           // 输出: 单身邓, 25岁!
           System.out.println(staff.getName() + ", " + staff.getAge() + "岁!");
       }
      
    • BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) 由一个旧的BiFunction以及一个旧的Function得到一个新的BiFunction<T, U, V>。
      假设: 现有式子biFunctionC = biFunctionA.andThen(functionB),biFunctionA泛型为<P1, T1, R1>, functionB泛型为<R1, R2>。
      那么, 上述式子的逻辑是:先运行biFunctionA<P1, T1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, T1, R2>的biFunctionC<P1, T1, R2>。
      使用示例:

       /**
        * <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after):
        *     由一个旧的BiFunction以及一个旧的Function得到一个新的BiFunction<T, U, V>。
        *
        * 假设:现有式子biFunctionC = biFunctionA.andThen(functionB),
        *      biFunctionA泛型为<P1, T1, R1>, functionB泛型为<R1, R2>。
        *
        * 那么,上述式子的逻辑是:先运行biFunctionA<P1, T1, R1>的apply方法,然后将其返回值
        *                     作为functionB<R1, R2>的apply方法的入参,执行
        *                     functionB<R1, R2>的apply方法,返回一个泛型为
        *                     <P1, T1, R2>的biFunctionC<P1, T1, R2>。
        */
       @Test
       public void test18() {
           BiFunction<Integer, String, Staff> biFunctionA = (x, y) -> {
               Staff s = new Staff();
               s.setAge(x);
               s.setName(y);
               return s;
           };
       
           Function<Staff, Map<String, Staff>> functionB = x -> {
               Map<String, Staff> map = new HashMap<>(4);
               map.put(x.getName(), x);
               return map;
           };
       
           BiFunction<Integer, String,  Map<String, Staff>> biFunctionC = biFunctionA.andThen(functionB);
       
           Map<String, Staff> map = biFunctionC.apply(25, "单身邓");
           // 输出: {单身邓=Staff(name=单身邓, age=25, staffNo=null)}
           System.out.println(map);
       }
      

    ToIntBiFunction<T, U>

    • int applyAsInt(T t, U u) 入参类型为T和U,(运行相关逻辑后)返回类型必为int。
      使用示例:
       /**
        * int applyAsInt(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为int。
        */
       @Test
       public void test19() {
           ToIntBiFunction<String, Double> toIntBiFunction = (x, y) -> Integer.parseInt(x) + y.intValue();
           int res = toIntBiFunction.applyAsInt("123000", 456.789);
           // 输出: 123456
           System.out.println(res);
       }
      

    ToLongBiFunction<T, U>

    • long applyAsLong(T t, U u) 入参类型为T和U, (运行相关逻辑后)返回类型必为long。
      使用示例:
       /**
        * long applyAsLong(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为long。
        */
       @Test
       public void test20() {
           ToLongBiFunction<String, Double> toLongBiFunction = (x, y) -> Integer.parseInt(x) + y.intValue();
           long res = toLongBiFunction.applyAsLong("123000", 456.789);
           // 输出: 123456
           System.out.println(res);
       }
      

    ToDoubleBiFunction<T, U>

    • double applyAsDouble(T t, U u) 入参类型为T和U,(运行相关逻辑后)返回类型必为double。
      使用示例:
       /**
        * double applyAsDouble(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为double。
        */
       @Test
       public void test21() {
           ToDoubleBiFunction<String, Double> toDoubleBiFunction = (x, y) -> Integer.parseInt(x) + y;
           double res = toDoubleBiFunction.applyAsDouble("123000", 456.789);
           // 输出: 123456.789
           System.out.println(res);
       }
      


    ^_^ 如有不当之处,欢迎指正

    ^_^ 参考资料
            《jdk api 1.8_google.CHM》

    ^_^ 测试代码托管链接
             https://github.com/JustryDeng…Jdk8Feature

    ^_^ 本文已经被收录进《程序员成长笔记》 ,笔者JustryDeng

    更多相关内容
  • async function

    万次阅读 2019-11-13 10:05:50
    async function 声明定义了一个异步函数,它返回一个AsyncFunction对象。异步函数 是指通过 事件循环(event loop) 异步执行的函数,通过返回一个隐式的 Promise 作为其结果。使用异步函数的代码的语法和结构更像...

    这篇文章多看几遍加深理解

    async function 声明定义了一个异步函数,它返回一个AsyncFunction对象。异步函数 是指通过 事件循环(event loop) 异步执行的函数,通过返回一个隐式的 Promise 作为其结果。使用异步函数的代码的语法和结构更像使用标准同步功能。(The async function declaration defines an asynchronous function, which returns an AsyncFunction object. An asynchronous function is a function which operates asynchronously via the event loop, using an implicit Promise to return its result. But the syntax and structure of your code using async functions is much more like using standard synchronous functions.

    语法

    async function name([param[, param[, ... param]]]) { statements }
    

    参数

    • name:函数名称
    • param:要传递给函数的参数。
    • statements:函数体语句。

    返回值:返回一个promise对象,将返回异步函数返回的值(如果异步函数是resolved则返回resolved的值;如果抛出异常,则rejected从异步函数中抛出的异常)。(A Promise which will be resolved with the value returned by the async function, or rejected with an uncaught exception thrown from within the async function.)

    异步函数可以包含await表达式,该表达式暂停异步函数的执行 并等待 Promise的执行结果返回,结果返回后就恢复异步函数的执行。

    await 关键字只在异步函数(async functions)内有效。如果在异步函数外使用它,会抛出语法错误。
    当异步函数暂停时,它调用的函数仍会继续执行。

    举例一:

    function resolveAfter5Seconds() {
        return new Promise(resolve => {
            setTimeout(() => {
                resolve('resolved');
            }, 5000);
        });
    }
    
    async function asyncCall() {
        console.log('calling');
        let result = await resolveAfter5Seconds();
        console.log(result); // 5s之后输出结果
    }
    
    asyncCall(); //返回的是一个promise对象
    // console.log(asyncCall()); // Promise { <pending> }
    

    运行效果:
    在这里插入图片描述
    举例二:

    let resolveAfter6Second = function () {
        console.log('start slow promise');
    
        return new Promise(resolve => {
            setTimeout(() => {
                resolve('slow');
                console.log('slow promise is done');
            }, 6000);
        })
    }
    
    let resolveAfter4Second = function () {
        console.log('start fast promise');
    
        return new Promise(resolve => {
            setTimeout(() => {
                resolve('fast');
                console.log('fast promise is done');
            }, 4000);
        })
    }
    
    let sequentialStart = async function () {
        console.log('sequential start');
        const slow = await resolveAfter6Second();
        console.log(slow);
        const fast = await resolveAfter4Second();
        console.log(fast);
    }
    
    sequentialStart()
    //立即输出
    // sequential start
    // start slow promise
    //再过6秒后输出
    // slow promise is done
    // slow
    // start fast promise
    //再过4秒后输出
    // fast promise is done
    // fast
    

    运行效果:
    在这里插入图片描述
    换一种await的写法,结果完全不同:两个计时器被同时创建

    let resolveAfter6Seconds = function () {
        console.log('start slow promise');
        return new Promise(resolve => {
            setTimeout(() => {
                resolve('slow');
                console.log('slow promise is done');
            }, 6000);
        })
    }
    
    let resolveAfter4Seconds = function () {
        console.log('start fast promise');
        return new Promise(resolve => {
            setTimeout(() => {
                resolve('fast');
                console.log('fast promise is done');
            }, 4000);
        })
    }
    
    let concurrentStart = async function () {
        console.log('concurrent start');
        let slow = resolveAfter6Seconds();
        let fast = resolveAfter4Seconds();
        console.log(await slow);
        console.log(await fast);
    }
    
    setTimeout(() => {
        concurrentStart();
    }, 2000);
    
    //2秒后执行
    // concurrent start
    // start slow promise
    // start fast promise
    //再过4秒后执行
    // fast promise is done
    //再过2秒后执行
    // slow promise is done
    // slow
    // fast
    

    运行效果:
    在这里插入图片描述
    在 concurrentStart 中,两个计时器被同时创建,接着执行await。等待的是 promise的resolve回调,resolve后面的代码( console.log(‘fast promise is done’);)会继续执行。
    这两个计时器同时运行。但是 await 仍旧是顺序执行的,第二个 await 还是得等待第一个执行完。在这个例子中,这使得先运行结束的输出出现在最慢的输出之后。
    也可以把 concurrentStart 改写成如下,运行效果一样:

    let resolveAfter6Seconds = function () {
        console.log('start slow promise');
        return new Promise(resolve => {
            setTimeout(() => {
                resolve('slow');
                console.log('slow promise is done');
            }, 6000);
        })
    }
    
    let resolveAfter4Seconds = function () {
        console.log('start fast promise');
        return new Promise(resolve => {
            setTimeout(() => {
                resolve('fast');
                console.log('fast promise is done');
            }, 4000);
        })
    }
    
    let concurrentPromise = async function () {
        console.log('concurrent start');
        return Promise.all([resolveAfter6Seconds(), resolveAfter4Seconds()]).then((messages) => {
            console.log(messages[0]); // slow
            console.log(messages[1]); // fast
        });
    }
    
    setTimeout(() => {
        concurrentPromise();
    }, 2000);
    //2秒后输出
    // concurrent start
    // start slow promise
    // start fast promise
    //再过6秒后输出
    // fast promise is done
    //再过2秒后输出
    // slow promise is done
    // slow
    // fast
    

    并行执行两个或更多的任务,如下例所示:

    let resolveAfter6Seconds = function () {
        console.log('start slow promise');
    
        return new Promise(resolve => {
            setTimeout(() => {
                resolve('slow');
                console.log('slow promise is done');
            }, 6000);
        })
    }
    
    let resolveAfter4Seconds = function () {
        console.log('start fast promise');
        return new Promise(resolve => {
            setTimeout(() => {
                resolve('fast');
                console.log('fast promise is done');
            }, 4000);
        })
    }
    
    let parallel = async function () {
        console.log('start paralel');
        
        await Promise.all([
            (async () => console.log(await resolveAfter6Seconds()))(),
            (async () => console.log(await resolveAfter4Seconds()))()
        ]);
    }
    
    setTimeout(parallel, 2000);
    //2秒后输出
    // start paralel
    // start slow promise
    // start fast promise
    //再过4秒后输出
    // fast promise is done
    // fast
    //再过2秒后输出
    // slow promise is done
    // slow
    

    运行效果:
    在这里插入图片描述
    如果希望并行执行两个或更多的任务,你必须像在parallel中一样使用await Promise.all([job1(), job2()])

    也可以把parallel改写成如下,运行效果一样:

    let resolveAfter6Seconds = function(){
        console.log('start slow promise');
        return new Promise(resolve => {
            setTimeout(() => {
                resolve('slow');
                console.log('slow promise is done');
            }, 6000);
        });
    }
    
    let resolveAfter4Seconds = function(){
        console.log('start fast promise');
        return new Promise(resolve =>{
            setTimeout(() => {
                resolve('fast');
                console.log('fast promise is done');
            }, 4000);
        })
    }
    
    let parallelPromise = function(){
        console.log('parallelPromise start');
        resolveAfter6Seconds().then(msg => console.log(msg));
        resolveAfter4Seconds().then(msg => console.log(msg));
    }
    
    setTimeout(() => {
        parallelPromise();
    }, 2000);
    //2秒后输出
    // parallelPromise start
    // start slow promise
    // start fast promise
    //再过4秒后输出
    // fast promise is done
    // fast
    //再过2秒后输出
    // slow promise is done
    // slow
    

    async/await和Promise#then对比以及错误处理:
    大多数异步函数(async functions )也可以使用 Promises函数 编写。然而,当涉及到错误处理时,异步函数不太容易出错。
    上面例子中的concurrentStart函数和concurrentPromise函数在功能上都是等效的。在concurrentStart函数中,如果任一awaited调用失败,它将自动捕获异常,异步函数执行中断,并通过隐式返回Promise将错误传递给调用者。
    在Promise例子中这种情况同样会发生,函数必须负责返回一个捕获函数完成的Promise。在concurrentPromise函数中,这意味着它从Promise.all([]).then()中返回一个Promise。事实上,在此示例的先前版本忘记了这样做!
    但是,async函数仍有可能然可能错误地忽略错误。
    以parallel异步函数为例。 如果它没有等待await(或 return)Promise.all([])调用的结果,则不会传播任何错误。
    虽然parallelPromise函数示例看起来很简单,但它根本不会处理错误! 这样做需要一个类似于return Promise.all([])处理方式。(详见

    使用async函数重写 promise 链

    返回 Promise的 API 将会产生一个 promise 链,它将函数分解成许多部分。例如下面的代码:

    function getProcessedData(url) {
        return downloadData(url)// returns a promise
            .catch(e => {
                return downloadFallbackData(url);// returns a promise
            })
            .then(v => {
                return processDataInWorker(v);// returns a promise
            })
    }
    
    

    可以重写为单个async函数:

    async function getProcessedData(url) {
        let v;
        try {
            v = await downloadData(url);
        } catch (e) {
            v = await downloadFallbackData();
        }
        return processDataInWorker(v);
    }
    

    在上述示例中,return 语句中没有 await 操作符,因为 async function 的返回值将被隐式地传递给 Promise.resolve。

    return await promiseValue;return promiseValue;的比较

    返回值隐式的传递给Promise.resolve,并不意味着return await promiseValue;,只是在功能上等同于返回return promiseValue;
    重写的上面代码,在processDataInWorker抛出异常时返回null:

    async function getProcessedData(url) {
      let v;
      try {
        v = await downloadData(url);
      } catch(e) {
        v = await downloadFallbackData(url);
      }
      try {
        return await processDataInWorker(v); // 注意 `return await` 和单独 `return` 的比较
      } catch (e) {
        return null;
      }
    }
    

    简单地写上return processDataInworker(v);将导致在processDataInWorker(v)出错时function返回值为Promise而不是返回null。

    return foo;return await foo;有一些细微的差异:
    return foo;不管foo是promise还是rejects都将会直接返回foo。相反地,如果foo是一个Promise,return await foo;将等待foo执行(resolve)或拒绝(reject),如果是拒绝,将会在返回前抛出异常。

    展开全文
  • function函数 function函数的具体用法

    万次阅读 2021-04-26 19:51:28
    我们在用Excel的过程当中经常会看到各种各样的函数...function函数——function()函数的具体用法function()函数的具体用法函数实际上是一个统一的代码块,你可以随时调用它。创建PHP函数的方法:所有函数的开头必须...

    我们在用Excel的过程当中经常会看到各种各样的函数,其中就包括funection函数,然而对于funectioe函数步了解的朋友一定不知道这一个函数是如何使用的,所以今天小编就来讲解这一个函数的具体使用方式是怎么样的。

    function函数——function()函数的具体用法

    function()函数的具体用法

    函数实际上是一个统一的代码块,你可以随时调用它。

    创建PHP函数的方法:

    所有函数的开头必须加上“function()”

    给函数命名:最好的命名方法是,函数拥有的名称和它所表现的功能相一致。

    名字可以包含字母或下划线(不可以包含数字)。

    加上一个“{”:函数的代码必须写在“{”符号之后。

    插入一段函数代码

    加上一个“}”:函数书写完毕后,必须加上“}”符号。

    MATLAB用function定义一个函数后怎么让这个函数生效是把这个M文件存到哪啊

    1、你可以通过在命令栏中输入function,点击右键或者按F1来查询function函数的帮助文档。

    2、在帮助文档中对function函数进行了详细的功能描述,使用方法的介绍。其基本形式为:function[]=fun();即为:[输出]=fun(输入)。

    4760cac684648d222d1db85147036948.png

    3、点击软件左上角新建,新建一个.m文件或者函数都可以进行编辑。

    4、其基本形式如图所示:第一行定义函数输入输出;第二三行百分号部分是注释部分,这里注意一定要写,方便以后查看该函数。第四五行编写函数的具体内容。

    5、这里举一个简单的求和例子。代码如下:

    function[c]=untitled(a,b)%UNTITLED求和%,求a+b的和:c=a+b;end。

    6、点击软件左上角保存,注意文件名一定要和函数名字一样。

    7、你可直接在命令函调用,也可在m文件或者另一个function函数中进行调用。

    8、你可以在右侧文件夹中点击你的函数文件,在函数详情中可以看到你的函数注释详情,方便以后函数的使用。

    以上就是有关funection函数该如何使用的所有内容,守着一个函数,其实非常的简单,只要多操作几遍就能够掌握,如果大家还想了解更多与之有关的内容,欢迎关注我们

    推荐阅读

    excel中函数的使用方法 excel函数的使用方法 | 文军营销在Excel中有超过300个函数供人们使用。今天我们先了解下excel中函数的使用方法,这些函数已经被组织和分类成不同的类型,在使用这些函数时可以先找到函数所在的种类,之...js函数 JS中创建函数的三种方式及区别 | 文军营销javascript函数的参数与大多数其他语言的函数的参数有所不同。函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,甚至可以不传参数。java...TRUE和FALSE这两个函数的具体使用方法 | 文军营销TRUE和FALSE这两个函数的具体使用方法,这个问题是我们很多人都很困惑的一个问题,TRUE和FALSE这两个函数的具体使用方法是我们非常常用的一个东西,也是...split函数的使用方法 split函数如何使用 | 文军营销在学习语言编程的过程当中,我们经常会遇见一些函数,其中split函数就是经常使用到的,他主要设置返回一个下标从零开始的一维数组,包含了指定数目的字制符串。那么这....strstr函数的用法 strstr函数正确使用 | 文军营销就会返回参数二,在参数一当中首次出现的地址,如果是错误的就会出现null,这也是我们在计算过程当中一个比较重要的函数,所以今天我们就来看一看strstr函数的具体使用...

    展开全文
  • function函数

    千次阅读 2021-05-22 16:27:37
    function()函数的具体用法请大侠具体告知,高分赠送。function()函数语法: function 函数名(参数1 [参数2]) { 函数体 return 返回值 } 举例:javascript 的 "。function" 是什么意思?。function跟(function(){... }...

    function()函数的具体用法

    请大侠具体告知,高分赠送。

    function()函数语法: function 函数名(参数1 [参数2]) { 函数体 return 返回值 } 举例:

    96d3a671c762e138e67c760032421239.png

    javascript 的 "。function" 是什么意思?

    。function跟(function(){... })();函数意义相同,叫做立即运行的匿名函数(也叫立即调用函数)。 js中可以这样创建一个匿名函数: (function(){do something...})() //或 (function(){do something...}()) 而匿名函数后面的小括号()是为了让匿名函

    HTML function函数怎么定义和调用

    完全忘记了。。 我想做一个计算平方的 最好给一个例子 感激不尽

    HTML function函数怎么定义和调用实例: function myFunction() { alert("Hello World。"); } Try it 扩展资料

    函数声明语法 (声明定义) function functionName(parameters) { 执行的代码 } 实例: function myFunction(a, b) { return a *

    function在MATLAB中怎么用

    2输出3个参数,创建一个有1输入(2维),(1维),还有全局变量的s-function。1.新建sfunction的C语言文件打开simulink,点击User-DefinedFunctions里面的S-FunctionExamples。这个里面有多个语言版本的模板,有C,C++,Ada。

    javascript 中 “ 。function(){}() ” 是什么意思?

    ( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法,要理解立即执行函数,需要先理解一些函数的基本概念。 函数声明: function fnName () {…};使用function关键字声明一个函数,再指定一个函数名。

    javascript中: (function(){})();如何理解?

    代码如下,不理解(function(){})();这个怎么理解?

    展开全文
  • Matlab S-function 使用总结

    万次阅读 多人点赞 2019-05-24 09:45:03
    近期在学习电机的智能控制,里面用到了Matlab中的S函数,在此先对S-function做一个小结。 S-function模块,位于Simulink/User-Defined Functions模块库中,S-function模块及其对话框如下图所示: S-function ...
  • Simulink S-function 学习及使用实例

    千次阅读 多人点赞 2020-11-19 23:35:19
    S-function 工作原理2.1 Simulink模块的数学关系2.2 Simulink 与S-function 仿真流程2.4 S-function回调程序3. M文件的S-function 模板4. 使用实例4.1 S-function实现离散系统总结 前言 本文介绍了s-function 的...
  • function—— Verilog的函数

    千次阅读 2020-06-02 21:52:34
    在程序中经常看到一个`function`,之前对其不太了解,正好趁着这个例子来看一下`verilog`中的函数功能——function
  • java8中的闭包Function/BiFunction

    千次阅读 2021-01-15 00:36:18
    先上java的闭包(利用Function和BiFunction实现) Function /** * @param num * @param function * @return * @desc 使用JDK8 Function函数 */ private Integer compute(Integer num, Function<Integer, ...
  • Java函数式编程(一)–Function的使用

    千次阅读 2019-08-15 00:50:52
    在函数式编程中,我们用的最多的往往是Function接口.通常来说,我们很少会直接使用这个接口,但是在Java的函数式编程中,许多组件都会与这个接口有关.需要注意的是,很多人会混淆Java8中新增的Stream API与函数式编程的...
  • 在使用sklearn训练完分类模型后,下一步就是要验证一下模型的预测结果,对于分类模型,sklearn中通常提供了predict_proba、predict、decision_function三种方法来展示模型对于输入样本的评判结果。 说明一下,在...
  • function函数封装

    千次阅读 2021-12-15 20:18:32
    function函数封装 std::function是一种通用、多态的函数封装,它的实例可以对任何可以调用的目标实体进行存储、复制和调用操作,它也是对 C++中现有的可调用实体的一种类型安全的包裹(相对来说,函数指针的调用...
  • Spring Cloud Function Spel表达式注入

    千次阅读 2022-04-05 00:49:33
    Spring Cloud Function Spel表达式注入 漏洞概述 Spring Cloud Function 是基于Spring Boot 的函数计算框架(FaaS),支持基于SpEL的函数式动态路由。在特定配置下,3 <= 版本 <= 3.2.2( commit dc5128b 之前...
  • Function create_function() is deprecated

    千次阅读 2020-08-31 13:39:28
    或直接封装为一个函数,可实现更好地复用: function decodeUnicode($str){ return preg_replace_callback('/\\\\u([0-9a-f]{4})/i', function($matches){return iconv("UCS-2BE","UTF-8",pack("H*", $matches[1...
  • error: called object ‘xxx’ is not a function or function pointer| 导致原因:数学表达式错误 或 使用了某些数学函数却没有导入包含它的头文件 解决办法: 1、检查代码中的数学表达式是否书写错误,常见的错误...
  • 【Java8】Function 讲解

    千次阅读 2020-02-20 17:05:41
    Java8 添加了一个新的特性Function,顾名思义这一定是一个函数式的操作。我们知道Java8的最大特性就是函数式接口。所有标注了@FunctionalInterface注解的接口都是函数式接口,具体来说,所有标注了该注解的接口都将...
  • tfrecord文件的map在使用的时候所踩的坑总结(map、py_function、numpy_function) tensorflow2.x之由dataset.map引发出的关于tf.py_function以及tf.numpy_function问题 本系列文章将深入详解这是哪个函数,即tf....
  • Function call stack: train_function->train_function->train_function 开始以为只是训练的问题,搜了下相关的问题以为是内存相关的错误,但设置内存后没有用,之后才注意到上面的报错说明了信息。 Fail...
  • Spring Cloud Function SpEL 漏洞复现

    千次阅读 2022-03-30 17:26:14
    Spring Cloud Function SpEL表达式注入漏洞,远程攻击者在无需认证的情况下,成功利用此漏洞可实现任意代码执行。
  • C++11 function类模板

    万次阅读 多人点赞 2018-10-21 02:14:49
    std::function 1. std::function 简介 类模板std :: function是一个通用的多态函数包装器。 std :: function的实例可以存储,复制和调用任何可调用的目标 :包括函数,lambda表达式,绑定表达式或其他函数对象,...
  • Java8之Function接口

    万次阅读 2019-10-14 11:05:06
    Java8 添加了一个新的特性Function,是一个函数式接口 所有标注了@FunctionalInterface注解的接口都是函数式接口,具体来说,所有标注了该注解的接口都将能用在lambda表达式上。 先看源码 @FunctionalInterface ...
  • TensorFlow 2.0 常用模块5:@tf.function

    千次阅读 多人点赞 2020-01-09 20:21:31
    此时,TensorFlow 2.0 为我们提供了 tf.function 模块,结合 AutoGraph 机制,使得我们仅需加入一个简单的 @tf.function 修饰符,就能轻松将模型以图模式运行! 本篇文章将介绍: @tf.function 基础使用方法; ...
  • Python中的Function定义方法

    千次阅读 2020-12-29 08:44:21
    下面就先定义一个函数:代码如下:def foo():print('function')foo()在上述代码中,定义了一个名为foo的函数,这个函数没有参数。最后一行代码的功能是调用这个函数。这是一个函数的最简单形式。下面来介绍一下有参数...
  • S-Function模块C语言实现

    千次阅读 2019-04-17 10:55:03
    S-Function可以使用Matlab,C,C++等语言来辩,使用MEX工具,将C,C++的S-Function编译成MEX-文件,在需要的时候,他们可与其它的MEX-文件一起动态地链接到Matlab中。 S-Function范例: Simulink提供了一个S-...
  • JDK不仅提供的这些函数式接口,其中一些接口还为我们提供了实用的默认方法,这次我们来介绍一下Consumer、Predicate、Function复合。
  • ElasticSearch - function_score详解

    千次阅读 2020-05-28 15:53:04
    1. 前言 在使用 Elasticsearch 进行全文搜索时,搜索结果默认会以文档的相关度...Elasticsearch提供了function_score功能来满足我们的需求。 2. function_score简介 在使用ES进行全文搜索时,搜索结果默认会以文档的相
  • Matlab中function函数的使用

    千次阅读 2020-12-14 18:26:55
    目录 语法 说明 示例 包含一个输出的函数 ...function [y1,...,yN] = myfun(x1,...,xM)声明名为myfun的函数,该函数接受输入x1,...,xM并返回输出y1,...,yN。此声明语句必须是函数的第一个可执行代码......
  • Java 8中的Function.apply方法参考文献 java.util.function.Function是一个接口,已经在Java 8中引入。 Function是一个函数接口。 因此它可以用来接受lambda表达式。 函数接受一个参数并返回结果。 函数接口包含一种...
  • std::function详解

    千次阅读 多人点赞 2021-03-25 15:51:52
    std::function详解
  • Matlab中function函数使用操作方法

    千次阅读 2021-04-18 03:21:44
    亲们或许不知道Matlab中function函数如何使用,那么今天小编就讲解Matlab中function函数使用操作方法哦,希望能够帮助到大家呢。Matlab中function函数使用操作方法打开Matlab,点击新建->函数,默认创建一个名为...
  • runtime-core.esm-bundler.js:6620 [Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance. at <Switch value=1 on-update:value=fn<on-update:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,564,236
精华内容 2,225,694
关键字:

function