Promise 解决阻塞式同步,将异步变为同步
Posted 勇敢*牛牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Promise 解决阻塞式同步,将异步变为同步相关的知识,希望对你有一定的参考价值。
Promise 解决阻塞式同步,将异步变为同步
一、样式
var p = new Promise(function(reslove,reject)
reslove()//在构造的时候就执行这个函数了
);
p.then(function()
).catch(function()
)
————————————————————————————————————————————————————————————————————————————————————
new Promise(function(resolve,reject)
resolve();
).then(function()
// resolve时执行
,function()
// reject时执行
)
Promise
需要实例化完成创建一个Promise
对象- 在
Promise
实例化的构造函数中传入一个回调函数 - 回调函数中有两个参数,一个是
resolve
,一个是reject
- 当成功后调用
resolve
函数,失败后调用reject
函数 - 并且可以通过
resolve
或者reject
函数传递一个参数 - 给
Promise
实例化的对象执行两个方法一个是then
,一个 是catch
- 这两个方法中有两个回调函数,当执行
resolve
时,调用then
中回调函数,当执行reject
时调用catch
中的回调函数 - 在Promise实例化的构造中只能调用一次resolve或者一次 reject,调用一次后,再次调用任何一个resolve或者reject都是无效的
顺序输出异步abc
new Promise(function(resolve,reject)
setTimeout(function()
resolve()
,1000)
).then(function()
console.log('a');
return new Promise(function(resolve,reject)
setTimeout(function()
resolve()
,500)
)
).then(function()
console.log('b');
return new Promise(function(resolve,reject)
setTimeout(function()
resolve()
,1000)
)
).then(function()
console.log('c');
)
输出:
a
b
c
顺序输出异步红绿灯
function setTime(time)
return new Promise(function(resolve,reject)
setTimeout(function()
resolve()
,time)
)
setTime(100).then(function()
console.log('黄灯');
return setTime(1000)
).then(function()
console.log('绿灯');
return setTime(500)
).then(function()
console.log('红灯');
)
封装返回一个Promise对象
//次函数返回一个Promise对象
function setTime(time)
return new Promise(function(resolve,reject)
setTimeout(function()
resolve();
,time);
)
Promise对象执行方法then
setTime().then(function()
console.log('aaa');
)
//aaa
连缀使用Promise
function setTime(time)
return new Promise(function(resolve,reject)
setTimeout(function()
resolve();
,time);
)
setTime(500).then(function()
console.log('aaa');
return setTime(1000);
).then(function()
console.log('bbb');
return setTime(100);
).then(function()
console.log('ccc');
)
aaa
bbb
ccc
预加载图片
让异步变成一个阻塞式同步
function loadImage(src)
return new Promise(function(resolve,reject)
var img = new Image();
img.src = src;
/* 加载完成时执行一下代码 */
img.onload = function()
/* 执行resolve回调函数,传入参数img对象 */
resolve(img)
)
var arr = [];
/* Promise对象构造的时候执行了回调函数resolve,而执行resolve会调用方法then中的回调函数 */
loadImage("./img/img_15.JPG").then(img =>
arr.push(img)
return loadImage("./img/img_16.JPG")
).then(img =>
arr.push(img)
return loadImage("./img/img_17.JPG")
).then(img =>
arr.push(img)
console.log(arr);
)
function loadImage(src)
return new Promise(function(resolve,reject)
var img = new Image();
img.src = src;
img.onload = function()
resolve(img)
img.onerror = function()
reject(src)
)
//错误时执行代码
var arr = [];
loadImage("./img/img_11.JPG").then(img =>
arr.push(img)
).catch(function(src)
console.error("error:"+src);
)
连续then时,相当于自动创建一个return promise并且执行resolve
new Promise(function(resolve,reject)
setTimeout(function()
resolve();
,500);
).then(function()
console.log("aa");
// 连续then,并没有return新的Promise时,相当于自动return Promise执行了resolve
// return new Promise(function(resolve,reject)
// resolve();
// )
).then(function()
console.log("bb");
)
两种快捷写法
Promise.resolve().then(function()
)
Promise.reject().catch(function()
)
图片整体预加载
- 先把所有异步使用Promise封装后放在一个数组中
- 然后通过Promise.all传入这个数组,这时候
- 所有异步执行resolve传入的参数就会被按照
- 顺序放在一个数组中,并且通过then中参数返回
function loadImage(src)
return new Promise(function(resolve,reject)
var img = new Image();
img.src = src;
img.onload = function()
resolve(img)
img.onerror = function()
reject(src)
)
arr = [];
for(var i=15;i<19;i++)
var p = loadImage(`./img/img_$i.JPG`);
arr.push(p);
console.log(arr);
Promise.all(arr).then(function(list)
list.forEach(item=>console.log(item));
)
谁先加载完就显示谁
Promise.race(arr).then(function(img)
console.log(img);
)
最简点的异步加载async,awiat
function loadImage(src)
return new Promise(function(resolve,reject)
var img = new Image();
img.src = src;
img.onload = function()
resolve(img)
img.onerror = function()
reject(src)
)
init();
async function init()
arr = [];
for(var i=15;i<19;i++)
/*自动等待将loadImage函数执行的resolve函数的结果值返回给p*/
var p = await loadImage(`./img/img_$i.JPG`);
arr.push(p);
console.log(arr);
- 异步可以包装成一个promise函数
- await 只能等待Promise,其他的异步都不能等待
- 要使用await ,就需要在await所属的函数外使用async
- 没有async不能单独使用await
- async函数执行后将会返回一个promise对象
- async函数中return 结果就相当于promise执行了resolve(return的结果)
当使用try catch拦截promise中reject时,必须放在async await函数中
因为这个是异步等待后才报错的
async function init()
try
await loadImage("./img/img_14.JPG").then(function(img)
console.log(img);
)
catch(e)
console.log(e)
宏任务和微任务
执行顺序
同步-->微任务-->微任务中的微任务-->宏任务-->宏任务中的微任务-->微任务中的宏任务-->微任务中的宏任务中的微任务-->宏任务中宏任务
new Promise(function (res, rej)
// console.log(2);
)
.then(function ()
// console.log(3);
Promise.resolve().then(function ()
// console.log(5);
setTimeout(function ()
console.log(6);
Promise.resolve().then(function ()
console.log(7);
);
setTimeout(function ()
console.log(8);
, 0);
, 0);
);
)
.then(function ()
// console.log(4);
);
setTimeout(function ()
// console.log(9);
new Promise(function (res)
res();
// console.log(10);
).then(function ()
// console.log(11);
);
);
Promise.resolve().then(function ()
setTimeout(function ()
Promise.resolve().then(function ()
// console.log(12);
);
// console.log(13);
, 0);
);
setTimeout(function ()
setTimeout(function ()
setTimeout(function ()
Promise.resolve().then(function ()
console.log(14);
);
console.log(15);
, 0);
console.log(16);
, 0);
// console.log(17);
, 0);
// console.log(18);
new Promise(function (res)
// console.log(19);
setTimeout(function ()
// console.log(20);
, 0);
);
以后看…………………………
console.log(1);
document.addEventListener("14", function ()
console.log(14);
);
new Promise(function (resolve)
resolve();
console.log(2);
setTimeout(function ()
console.log(3);
, 0);
Promise.resolve().then(function ()
console.log(4);
setTimeout(function ()
console.log(5);
, 0);
setTimeout(function ()
(async function ()
console.log(6);
return function ()
console.log(7);
;
)()以上是关于Promise 解决阻塞式同步,将异步变为同步的主要内容,如果未能解决你的问题,请参考以下文章
将已经存在的异步请求callback转换为同步promise
promise 的基本概念 和如何解决js中的异步编程问题 对 promis 的 then all ctch 的分析 和 await async 的理解