zoukankan      html  css  js  c++  java
  • 异步编程(回调函数,promise)

    一、回调函数

    概念:一般情况下,程序会时常通过API调用库里所预先备好的函数。但是有些库函数却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function),也就是一个函数作为另外一个函数的参数使用。如果需要得到一个函数内部的异步操作的结果,这时候必须通过回调函数来获取。

    ②推导:

    ③数组遍历中使用的回调函数

    • every() 方法测试数组的所有元素是否都通过了指定函数的测试
    function isBelowThreshold(currentValue) {
        return currentValue < 40;
      }
      var array1 = [1, 30, 39, 29, 10, 13];
      console.log(array1.every(isBelowThreshold));//  true
    • forEach() 方法对数组的每个元素执行一次提供的函数
    var array1 = ['a', 'b', 'c'];
    array1.forEach(function(element) {
      console.log(element);
    });
    // expected output: "a"
    // expected output: "b"
    // expected output: "c"
    • some() 方法测试数组中的某些元素是否通过由提供的函数实现的测试
    var array = [1, 2, 3, 4, 5];
    var even = function(element) {
      // checks whether an element is even
      return element % 2 === 0;
    };
    console.log(array.some(even));
    // expected output: true
    • includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false
    var array1 = [1, 2, 3];
    console.log(array1.includes(2));
    // expected output: true
    • map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果
    var array1 = [1, 4, 9, 16];
    // pass a function to map
    const map1 = array1.map(x => x * 2);
    console.log(map1);
    // expected output: Array [2, 8, 18, 32]
    •  reduce() 方法对累加器和数组中的每个元素(从左到右)应用一个函数,将其减少为单个值。
    const array1 = [1, 2, 3, 4];
    const reducer = (accumulator, currentValue) => accumulator + currentValue;
    console.log(array1.reduce(reducer));
    // 1 + 2 + 3 + 4
    // expected output: 10
    
    console.log(array1.reduce(reducer, 5));
    // 5 + 1 + 2 + 3 + 4
    // expected output: 15

    ④ajax请求里使用回调函数

    function get(url,callback){
        var oReq=new XMLHttpRequest()
        // 当请求加载成功以后要调用指定的函数
        oReq.onload=function(){
            // 现在需要得到这里的oReq.oReq.responseText
            callback(oReq.responseText)
        }
        oReq.open('get',url,true)
        oReq.send()
    }
    get('data.json',function(data){
        console.log(data)
    })

    ⑤ES6的find和findindex方法

    // find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
    var array1 = [5, 12, 8, 130, 44];
    var found = array1.find(function(element) {
      return element > 10;
    });
    console.log(found);
    // expected output: 12
    // findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
    var array1 = [5, 12, 8, 130, 44];
    function findFirstLargeNumber(element) {
      return element > 13;
    }
    console.log(array1.findIndex(findFirstLargeNumber));
    // expected output: 3
    // 原理
    var users=[
        {id:1,name:'曹操'},
        {id:2,name:'许褚'},
        {id:3,name:'典韦'},
        {id:4,name:'于禁'},
    ]
    Array.prototype.myFind=function(conditionFunc){
        for(var i=0;i<this.length;i++){
            if(conditionFunc(this[i],i)){
                return this[i]
            }
        }
    }
    var ret=users.myFind(function(item,index){
        return item.id===4
    });
    console.log(ret);//{ id: 4, name: '于禁' }

    二、promise

    ①无法保证顺序的代码

    var fs=require('fs');
    // 读取a.txt(里面包括文本 aaa)文件
    fs.readFile('./a.txt','utf8',function(err,data){
        if(err){
            // 抛出异常:阻止程序的执行,把错误信息打印到控制台
            throw err
        }
        console.log(data)
    })
    // 读取b.txt(里面包括文本 bbb)文件b
    fs.readFile('./b.txt','utf8',function(err,data){
        if(err){
            // 抛出异常:阻止程序的执行,把错误信息打印到控制台
            throw err
        }
        console.log(data)
    })
    // 读取c.txt(里面包括文本 ccc)文件
    fs.readFile('./c.txt','utf8',function(err,data){
        if(err){
            // 抛出异常:阻止程序的执行,把错误信息打印到控制台
            throw err
        }
        console.log(data)
    })

    ②通过回调嵌套的方式来保证顺序

    var fs=require('fs');
    // 读取a.txt(里面包括文本 aaa)文件
    fs.readFile('./a.txt','utf8',function(err,data){
        if(err){
            // 抛出异常:阻止程序的执行,把错误信息打印到控制台
            throw err
        }
        console.log(data);
        // 读取b.txt(里面包括文本 bbb)文件b
        fs.readFile('./b.txt','utf8',function(err,data){
            if(err){
                // 抛出异常:阻止程序的执行,把错误信息打印到控制台
                throw err
            }
            console.log(data);
            // 读取c.txt(里面包括文本 ccc)文件
            fs.readFile('./c.txt','utf8',function(err,data){
                if(err){
                    // 抛出异常:阻止程序的执行,把错误信息打印到控制台
                    throw err
                }
                console.log(data)
            });
        });
    });

    ③为了解决回调嵌套编码方式带来的问题(代码不美观,并且不好维护),ecmascript 6里增加了一个API:promise

    • promise代码执行顺序
    var fs=require('fs');
    console.log(1)
    // 创建promise容器:一旦建立,就开始执行里面的代码
    new Promise(function(){
        console.log(2);
        fs.readFile('./a.txt','utf8',function(err,data){
            if(err){
                throw err;
            }
            console.log(3);
            console.log(data)
        });
    });
    console.log(4)
    //执行顺序是:1   2   4  3  aaa
    • promise图示

    • promise基本语法
    var fs=require('fs');
    // 创建promise容器:一旦建立,就开始执行里面的代码
    var p1=new Promise(function(resolve,reject){
        fs.readFile('./aa.txt','utf8',function(err,data){
            if(err){
                // promise容器中的任务失败,pending状态变为rejectd
                reject(err)
            }else{
                // promise容器中的任务成功,pending状态变为resolved
                // 这里调用的resolve方法就是下面then方法传递的第一个参数function(data){}
                resolve(data)
            }
        });
    });
    // 当p1成功以后,执行then方法的function(data){}
    // 当p1失败以后,执行then方法的function(err){}
    p1.then(function(data){
        console.log(data)
    },function(err){
        console.log('文件读取失败',err)
    })

    • 解决读取多个文件的嵌套问题
    var fs=require('fs');
    // 读取a.txt(里面包括文本 aaa)文件
    var p1=new Promise(function(resolve,reject){
        fs.readFile('./a.txt','utf8',function(err,data){
            if(err){
                reject(err)
            }else{
                resolve(data)
            }
        });
    });
    // 读取b.txt(里面包括文本 bbb)文件
    var p2=new Promise(function(resolve,reject){
        fs.readFile('./b.txt','utf8',function(err,data){
            if(err){
                reject(err)
            }else{
                resolve(data)
            }
        });
    });
    // 读取c.txt(里面包括文本 ccc)文件
    var p3=new Promise(function(resolve,reject){
        fs.readFile('./c.txt','utf8',function(err,data){
            if(err){
                reject(err)
            }else{
                resolve(data)
            }
        });
    });
    // then处理:当return一个promise对象,后续的then方法中的第一个参数就会接收这个对象
    p1.then(function(data){
        console.log(data);
        return p2//后续的then里面的第一个参数会作为p2的resolve
    },function(err){
        console.log('文件读取失败',err)
    }).then(function(data){
        console.log(data);
        return p3//后续的then里面的第一个参数会作为p3的resolve
    },function(err){
        console.log('文件读取失败',err)
    }).then(function(data){
        console.log(data);
        console.log('end')
    },function(err){
        console.log('文件读取失败',err)
    })

    • 封装promise版本的readFile方法

    var fs=require('fs');
    // 读取文件封装函数
    function pReadFile(filePath){
        return new Promise(function(resolve,reject){
            fs.readFile(filePath,'utf8',function(err,data){
                if(err){
                    reject(err)
                }else{
                    resolve(data)
                }
            });
        })
    }
    
    pReadFile('./a.txt').then(function(data){
        console.log(data);
        return pReadFile('./b.txt')
    }).then(function(data){
        console.log(data);
        return pReadFile('./c.txt')
    }).then(function(data){
        console.log(data);
    })

    ⑤promise使用场景:数据来源于多个数据接口,形成的嵌套问题

    ⑥mongoose所有的API都支持promise

    ⑧参考文章:http://es6.ruanyifeng.com/#docs/promise

  • 相关阅读:
    AngularJs学习笔记--directive
    angularjs 路由(1)
    走进AngularJs(一)angular基本概念的认识与实战
    angularjs- 快速入门
    从angularJS看MVVM
    中软国际 问题一php的优缺点
    elasticsearch head安装后无法连接到es服务器问题
    Laravel5.3 流程粗粒度分析之bootstrap
    mysql执行大量sql语句
    Laravel RuntimeException inEncrypter.php line 43: The only supported ciphers are AES-128-CBC and AES-256-CBC with the correct key lengths
  • 原文地址:https://www.cnblogs.com/EricZLin/p/9308104.html
Copyright © 2011-2022 走看看