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
原文地址:https://www.cnblogs.com/fengbaba/p/13742427.html