JS:Promise异步编程的一种解决方案

发布时间 2023-09-20 15:47:09作者: July_Zheng

 Promise

是异步编程的一种解决方案,可以替代传统的解决方案--回调函数和事件。ES6统一了用法,并原生提供了Promise对象。作为对象,Promise有以下两个特点:(1)对象的状态不受外界影响。(2)Promise有三种状态,分别是 Pending (进行中)、Resolved (已完成)、Rejected (已失败) 一旦状态改变了就不会再变,也就是说任何时候Promise都只有一种状态。
 

基本用法-创建对象

// 可以通过Promise的构造函数创建Promise对象
var promise0 = new Promise((resolve,reject) => {
  setTimeout(()=>{
    console.log("hello world")
}, 2000)
})
console.log(promise0); //Promise {<pending>} 

//#通过执行函数控制Promise状态
let p1 = new Promise((resolve, reject) => {
    resolve(); //把状态切换为兑现
});
console.log(p1); //Promise {<fulfilled>: undefined}
p1.then( ()=>{ console.log('p1 then')}).catch( ( param )=>{ console.log('p1 catch')})

let p2 = new Promise((resolve, reject) => {
    reject(); //把状态切换为拒绝
});
p2.then( ()=>{ console.log('p2 then')}).catch( ( param )=>{ console.log('p2 catch')})
console.log(p2); //Promise {<rejected>: undefined}

 

编程风格-对象链式回调

// Promise解决异步,只是一种更好的编程风格
// 实现分三次输出字符串,第一次间隔1秒,第二次间隔4秒,第三次间隔3秒

// 函数回调
setTimeout(function () {
    console.log("First");
    setTimeout(function () {
        console.log("Second");
        setTimeout(function () {
            console.log("Third");
        }, 3000);
    }, 4000);
}, 1000);

// Promise
// 将嵌套格式变成了顺序格式
new Promise(function (resolve, reject) {
    setTimeout(function () {
        console.log("First");
        resolve();
    }, 1000);
}).then(function () {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log("Second");
            resolve();
        }, 4000);
    });
}).then(function () {
    setTimeout(function () {
        console.log("Third");
    }, 3000);
});



//链式回调
function greetPromise () {
    var promise = new Promise(function (resolve, reject){
      var res = "hello world"
      resolve(res)
    })
    return promise
  }
  greetPromise().then(v => {
    console.log(v+1)
    return v
  })
  .then (v => {
    console.log(v+2)
    return v
  })
  .then (v => {
    console.log(v+3)
  })


 

 

 

对象的then  catch

 var promise1 = new Promise(function(resolve, reject){ 
    setTimeout(function(){
        resolve("参数0!"); //代码正常执行!
    }, 1000);
});
promise1.then(function(successMessage){ 
    console.log("已成功" + successMessage+'1,');
     // return 333;     //return 333 时还会继续执行下一个.then
     throw "An error";   //throw  时还会继续执行下一个.catch
}).then(function(successMessage){ 
    console.log("已成功" + 333+'2,');
}).catch((message)=>{
    console.log("err! " + message+'3,');
})
//以上代码执行完成,界面会出现 (控制台输出):已成功参数0!1,   err! An error3,
console.log("promise1 输出顺序2",promise1); //Promise {<pending>} 
 

 

//用Promise-解决回调地狱问题
const imgPromise = (url) => {
    return new Promise((resolve, reject) => {
        const img = new Image();
        img.src = url;
        img.onload = () => {
            resolve(img);
        }
        img.onerror = () => {
            reject(new Error('图片加载出现错误'));
        }
    });
}
imgPromise('https://XXX.png').then(img => {
    document.body.appendChild(img);
}).catch(err => {
    const p = document.createElement('p');
    p.innerHTML = err;
    document.body.appendChild(p);
});

 

异步

异步函数 async function 中可以使用 await 指令,await 指令后必须跟着一个 Promise,异步函数会在这个 Promise 运行中暂停,直到其运行结束再继续运行。

失败reject :解决async/await中的promise返回错误reject的问题,错误捕获:try{ }catch(e){  }

 async function asyncFunction2() {
    try {
       //可以保证多个 Promise 按顺序执行
     var res1=  await  new Promise((resolve,reject) => { reject("参数0!");   })  
     var res2=   await  new Promise((resolve,reject) => { reject("参数1!");    })  
     console.log( "返回值",res1, res2 ); //返回值 undefined undefined
   
   }catch(e){      
     console .log (e)   //参数0!
    }  
       
};  
asyncFunction2();  //开始调用函数

 

成功resolve

async function asyncFunction() { 
    try { 
        //可以保证多个 Promise 按顺序执行 
    var res1=  await  new Promise((resolve,reject) => { resolve("参数0!");   }) .then(function(successMessage){    return ("已成功0"+successMessage);  }) ;
    var res2=   await  new Promise((resolve,reject) => { resolve("参数1!");    })    
    console.log( "返回值",res1, res2 ); //返回值 已成功0参数0! 参数1!
    
   }catch(e){    }
       
};   
 asyncFunction();  //开始调用函数

 

注意:异步函数 async function 中可以使用 await 指令,尽量不使用链式

失败reject -

async function asyncFunction2() { 
    try { 
        //可以保证多个 Promise 按顺序执行 
    var res1=  await  new Promise((resolve,reject) => { reject("参数0!");   }) .then(function(successMessage){    return ("已成功0"+successMessage);  }) .catch( ()=>{});
    var res2=   await  new Promise((resolve,reject) => { reject("参数1!");    })    .catch( ()=>{});
    console.log( "返回值",res1, res2 ); //返回值 undefined undefined 
   }catch(e){    }
       
};   
asyncFunction2();  //开始调用函数
 

 async function asyncFunction3() { 
    try { 
      //可以保证多个 Promise 按顺序执行 
    var res1=  await  new Promise((resolve,reject) => { reject("参数0!");   }) .then(function(successMessage){    return ("已成功0"+successMessage);  }) .catch( (param)=>{  return ("catch"+param); });
    var res2=   await  new Promise((resolve,reject) => { reject("参数1!");    }).catch( (param)=>{  return ("catch"+param); });
    console.log( "返回值",res1, res2 ); //返回值 catch参数0! catch参数1!
    
   }catch(e){ }
       
};   
asyncFunction3();  //开始调用函数

 其他:Promise的静态方法all  race