zoukankan      html  css  js  c++  java
  • javascript异步编程,promise概念

    javascript 异步编程

    概述

    • 采用单线程模式工作的原因: 避免多线dom操作同步问题,javascript的执行环境中负责执行代码的线程只有一个

    内容概要

    • 同步模式和异步模式
    • 事件循环和消息队列
    • 异步编程的几种方式
    • Promise 异步方案、宏任务/微任务队列
    • Generator异步方案、async/await语法糖

    同步模式(synchronous)

    • 复杂运算耗时较多时阻塞后面代码执行

    异步模式()

    • 耗时任务用异步模式去处理 用回调函数
    • 代码执行顺序混乱
    • 异步同步说的是执行代码的线程是单线程
    console.log('global begin')
    setTimeout(function timer1 () {
        console.log('timer1 invoke')
    }, 1800)
    setTimeout(function timer2 () {
        console.log('timer2 invoke')
        setTimeout(function inner () {
            console.log('inner invoke')
        }, 1000)
    }, 1000)
    console.log('global end')

    回调函数

    • 所有异步编程方案的根基

    promise概述

    • promise 是 es6 提出的一个异步解决方案,比传统回调事件的写法更加合理更加强大,主要还是优雅
    • promise 有 pending(等待中),fulfilled(已成功),rejected(已失败),只有异步操作的结果才能够将状态改变,且只会有 pending->fulfilled 或者 pending->rejected,只要状态改变,会一直保持这个结果
    • promise的回调函数都会被挂入到回调队列中
    • then方法会返回一个全新的promise对象
    • 每一个then方法都是在为上一个then返回的promise添加状态
    • 前面then方法中的回调函数的返回值都会作为后面then方法的参数
    • 如果回调函数返回的是promise,那么后面then方法的回调会等待她的结束
    const p = new Promise((resolve, reject) => {
        if (true) {
            resolve("成功"); //将状态由pending->fulfilled
        } else {
            reject("失败"); //将状态由pending->rejected
        }
    });
    console.log(p);

    promise 基本方法

    // promise 方式 ajax
    
    function ajax(url){
        return new Promise(function(resolve,reject){
            var xhr = new XMLHttpRequest();
            xhr.open('GET',url);
            xhr.responseType = 'json';
            xhr.onload = function(){
                if(this.status  === 200){
                    resolve(this.response);
                }else{
                    reject(new Error(this.statusText));
                }
            }
            xhr.send();
        })
    }
    
    ajax("./package.json").then(res=>{
        console.log(res);
    }).catch(err=>{
        console.log(err);
    })
    ajax("./1.json").then(res=>{
        console.log(res);
    }).catch(err=>{
        console.log(err);
    })

    promise 静态方法

    • resolve 返回一个成功的promise对象
    • reject 快速创建一个一定是失败的promise对象
    function ajax(url){
        return new Promise(function(resolve,reject){
            var xhr = new XMLHttpRequest();
            xhr.open('GET',url);
            xhr.responseType = 'json';
            xhr.onload = function(){
                if(this.status  === 200){
                    resolve(this.response);
                }else{
                    reject(new Error(this.statusText));
                }
            }
            xhr.send();
        })
    }
    // Promise.resolve("成功").then(res=>{
        console.log(res);
    });//等价于 new Promise
    
    
    
    var promise = ajax("/aa");
    var promise2 =  Promise.resolve(promise)
    // promise === promise2

    并行执行

    • all
    • race
    // promise 并行执行
    function ajax(url){
        return new Promise(function(resolve,reject){
            var xhr = new XMLHttpRequest();
            xhr.open('GET',url);
            xhr.responseType = 'json';
            xhr.onload = function(){
                if(this.status  === 200){
                    resolve(this.response);
                }else{
                    reject(new Error(this.statusText));
                }
            }
            xhr.send();
        })
    }
    //all  等待所有
    
    var promiseAll = Promise.all([
        ajax("./package.json"),
        ajax("./package.json"),
        ajax("./package.json"),
        ajax("./package.json"),
        ajax("./package.json"),
        ajax("./package.json"),
        ajax("./package.json"),
        ajax("./package.json"),
        ajax("./package1.json")
    ]).then(res=>{
        console.log(res)// 所有成功才会执行
    }).catch(err=>{
        console.log(err);//任何一个失败都会执行
    });
    
    
    //race 只等待第一个结束的任务
    Promise.race([
        ajax("./package.json?a=1"),
        ajax("./package.json?a=2"),
        ajax("./package.json?a=3"),
        ajax("./package.json?a=4"),
        ajax("./package.json?a=5"),
        ajax("./package.json?a=6"),
        ajax("./package.json?a=7"),
        ajax("./package.json?a=8"),
        ajax("./package.json?a=9")
    ]).then(res=>{
        console.log(res);//返回第一个成功的
    }).catch(err=>{
        console.log(err);//返回第一个失败的
    })

    执行时序

    • promise 没有任何异步操作任然会执行异步回调
    • promise 是微任务不会重新排队本轮调用结束的末尾去执行
    • setTimeout等大多数api都是宏任务都需要重新排队
    console.log("A");
    
    setTimeout(function(){
        console.log("B")
    },0)
    
    Promise.resolve().then(res=>{
        console.log("C");
    
        setTimeout(function(){
           console.log("D")
        },0)
    })
    
    new Promise(function(resolve,reject){
        console.log("E");
    
        resolve("ok");
    }).then(res=>{
        console.log("F");
    });
    
    console.log("G")
    // A E G C F B D
  • 相关阅读:
    实现反转函数,即反转一个Null结尾的字符串
    给定两个字符串,确定其中一个字符串的字符重新排列后,能否变成另一个字符串
    IDL 常用字符串处理函数
    IDL创建进度条
    python中f'{}'用法
    Win10 pycharm中显示PyTorch tensorboard图
    torch.cat()和torch.stack()
    运筹学笔记6初始可行基
    运筹学笔记5单纯形法
    运筹学笔记4线性规划问题的几何特征
  • 原文地址:https://www.cnblogs.com/fengbaba/p/13742427.html
Copyright © 2011-2022 走看看