Promise如何使用?全方位解析,一篇搞懂异步
目录
什么是异步?
什么情况下用到promise?
promise所有回调参数
赋值写法
链式调用
promise.all
在函数中 return 一个 promise
用ajax网络请求配合 promise使用:
异步中的微任务队列
什么是异步?
异步:操作之间没啥关系,同时进行多个操作,操作之间不会有干扰(可以先往下执行,回头再执行上面的),代码复杂
同步:同时只能做一件事,上面数据执行完之后才能进行下个操作(从上到下),代码简单
什么情况下用到promise?
一般情况下是有异步操作时,使用Promise对这个异步操作进行封装
new ->构造函数(1.保存了一些状态信息 2.执行传入的函数)
在执行传入的回调函数时,会传入两个函数:resolve,reject 这两个本身又是函数
Promise将网络请求和最终处理代码进行分离
promise所有回调参数
resolve(value) — 如果任务成功完成并带有结果 value
reject(error) — 如果出现了 error,error 即为 error 对象。
异步任务顺利完成且返回结果值时,会调用 resolve 函数;而当异步任务失败且返回失败原因(通常是一个错误对象)时,会调用reject 函数
promise.then()成功调用
promise.catch() 失败调用 (这个有点像try..catch,不懂的可以点击蓝字去看哦)
promise.finally()成功失败都调用
赋值写法
let promise = new Promise(function(resolve, reject) { setTimeout(() => resolve("咚!"), 1000); }); // resolve 运行 .then 中的第一个函数 promise.then( result => alert(result), // 1 秒后显示 "咚!" error => alert(error) // 不运行 ); //或者 promise.then(alert); // 1 秒后显示 "咚!"
可以看到上面then有两个参数:
.then
的第一个参数是一个函数,该函数将在resolved 后运行并接收结果。
.then
的第二个参数也是一个函数,该函数将在 rejected 后运行并接收 error。
链式调用
自上到下挨着执行
new Promise(function(resolve, reject) { setTimeout(() => resolve(1), 1000); }).then(function(result) { alert(result); // 打印1 return result * 2; }).then(function(result) { alert(result); // 打印2 return result * 2; })
promise.all
promise.all这个方法返回一个新的promise对象,该promise对象在iterable参数对象里所有的promise对象都成功的时候才会触发成功,否则返回失败
常用技巧:
1.let urls = [ 'https://api.github.com/1', 'https://api.github.com/2', 'https://api.github.com/3' ]; // 将每个 url 映射(map)到 fetch 的 promise 中 let requests = urls.map(url => fetch(url)); // Promise.all 等待所有任务都 resolved成功 Promise.all(requests) .then(responses => console.log(responses) )); //会输出数组形式的这几个链接 //[https://api.github.com/1,https://api.github.com/2,https://api.github.com/3]
在函数中 return 一个 promise
1.function promisify(f) { return new Promise((resolve, reject) => { if (err) { reject(err); } else { resolve(result); } }) } // 用法: let Promises = promisify(参数); Promises(...).then(...);
附上MDN的关系图:
用ajax网络请求配合 promise使用:
1. function createPromise(url) { // resolve成功 reject失败 return new Promise(function (resolve, reject) { $.ajax({ // es6简写 url, dataType: 'json', success(arr) { resolve(arr); }, error(err) { reject(err) }, }) }); } // 同时满足返回成功 Promise.all([ createPromise('./arr.txt'), createPromise('./json.txt') // then然后的意思,then(function(){},function(){}),第一个返回成功,第二个函数失败 ]).then(function (arr) { // 解构赋值 // res1是第一个链接,res2是第二个链接 let [res1, res2] = arr; alert('全部成功'); alert(res1); alert(res2); }, function () { alert('至少有一个失败了') } /* then有两个参数第一个参数是一个函数,该函数将在resolved 后运行并接收结果。 第二个参数也是一个函数,该函数将在 rejected 后运行并接收 error。*/
异步中的微任务队列
只有在 JavaScript 引擎中执行完任务时,才开始执行任务队列中的任务。
队列(queue)中也是按先后顺序执行的,首先进入队列的任务会首先运行。
当一个 promise 准备就绪时,它的then/catch/finally处理程序就会被放入队列中:但是它们不会立即被执行。当 JavaScript 引擎执行完当前的代码,它会从队列中获取任务并执行它。
下面代码会先执行同步代码:
let promise = Promise.resolve(); promise.then(() => alert("2")); alert("1"); // 这个 1 先显示
如果我们需要确保一段代码在异步之后被执行,我们可以将它添加到链式调用的 .then
中
最后挑一种自己喜欢的方式书写就可以了,我刚开始看的时候也有点蒙蔽,其实就是为了从各个角度介绍promise,自己有个大概了解之后,用起来更顺手哦
我有话说: