JS:Promise异步编程的一种解决方案
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