加入收藏 | 设为首页 | 会员中心 | 我要投稿 银川站长网 (https://www.0951zz.com/)- 云通信、基础存储、云上网络、机器学习、视觉智能!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

怎样学习JS中的异步和Promise对象

发布时间:2023-08-04 12:55:48 所属栏目:语言 来源:
导读:今天这篇给大家分享的知识是“如何学习JS中的异步和Promise对象”,小编觉得挺不错的,对大家学习或是工作可能会有所帮助,对此分享发大家做个参考,希望这篇“如何学习JS中的异步和Promise对象&rdquo

今天这篇给大家分享的知识是“如何学习JS中的异步和Promise对象”,小编觉得挺不错的,对大家学习或是工作可能会有所帮助,对此分享发大家做个参考,希望这篇“如何学习JS中的异步和Promise对象”文章能帮助大家解决问题。

1、JS中的异步

1.1 同步

一般情况下,js的代码都是自上而下顺序运行的。例如:

let res = '';

res = '获取到的结果!';

console.log(res);

很容易理解,我给res赋了新值,然后输出res。这就是js的同步执行,这里的同步,并不是一起执行的意思,而是在一个线程里顺序执行的意思。因为JavaScript是单线程,所以所有程序都应该在一个线程里运行。

1.2 异步

但是有的时候,我们获取res的值是需要一点时间的,例如使用ajax向服务器发起请求,服务器响应以后返回结果,我们再将结果赋值给res。

这里使用setTimeout函数模拟数据请求,setTimeout也是一个异步函数。

let res = '';

setTimeout(()=>{

res = '获取到的结果!';

console.log('获取到结果了!',res);

},3000);

console.log('res',res);

可以看到,没有立刻获取到结果,而是3s后才获取到结果。

为什么会这样呢?

由于获取res它是一个异步操作,所以它会被分为两部分来执行,先调用setTimeout方法,然后把要执行的函数放到一个队列中。代码继续往下执行,当把所有的代码都执行完后,放到队列中的函数才会被执行。因为js的单线程机制,不允许它花费时间去等待异步函数的结果。

1.3 回调函数解决异步问题

既然异步函数的结果会再最后获取,那么我们就可以给异步函数中加一个回调函数,来处理获取到的数据。

let res = '';

setTimeout(()=>{

res = '获取到的结果!';

callback();

},3000);

function callback(){

console.log('获取到结果了!',res);

console.log('处理结果!');

}

console.log('res', res);

现在console.log('res', res);仍然没有获取到res,但是我们已经不需要它了,我们获取res的就是为了处理它,而使用callback函数就可以达到目的了!

1.4 回调地狱

1.3了解了可以通过调用函数解决无法获取结果的问题,但是它仍然是存在缺点的,如果只获取一次结果,那还好。但是如果我们在获取结果之后,还需要利用获取的结果再进行异步操作,那么又需要嵌套一层,又需要一次异步操作,再嵌套一层……

setTimeout(function(){

console.log("first");

setTimeout(function(){

console.log("second");

setTimeout(function(){

console.log("third");

setTimeout(function(){

console.log("fourth");

},2000);

},2000);

},2000);

},2000);

虽然上述代码会按照我们预期的方向运行,但是多层的嵌套让代码阅读和维护起来十分的困难。

2、Promise对象

2.1 Promise的基本使用

为了解决异步中的回调地狱问题,ES6引入了Promise对象,使得我们可以十分优雅地进行异步操作。

从语法上来说,Promise是一个对象,从它可以获取异步操作的消息。

let timeout = function(time){

return new Promise(function(resolve,reject){

setTimeout(function(){

resolve();

},time);

});

}

console.log("开始运行!");

timeout(2000).then(function(){

console.log("first");

return timeout(2000);

}).then(function(){

console.log("second");

return timeout(2000);

}).then(function(){

console.log("third");

return timeout(2000);

}).then(function(){

console.log("fourth");

return timeout(2000);

});

这样就解决了上述的回调地狱的问题。并且then也很容易理解,就是上一个异步函数执行完成后,接着要进行的操作。

同时Promise对象也可以通过resolve和reject传递参数:

let res = null;

let timeout = function(time){

return new Promise(function(resolve,reject){

setTimeout(function(){

res = false;

if(res){

resolve('res为true');

}else{

reject('res为false');

}

},time);

});

}

timeout().then((res)=>{

console.log(res);

}).catch((error)=>{

console.log(error);

})

这样就可以根据res的值来确定结果了。resolve()对应then的结果,而reject()对应catch的结果。这在axios的请求操作中是十分常见的。

2.2 async 和 await

mdn描述如下:

async函数是使用async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。

async和await的关系:

async函数可能包含0个或者多个await表达式。await表达式会暂停整个async函数的执行进程并出让其控制权,只有当其等待的基于promise的异步操作被兑现或被拒绝之后才会恢复进程。promise的解决值会被当作该await表达式的返回值。使用async / await关键字就可以在异步代码中使用普通的try / catch代码块。

function getProcessedData(url) {

return downloadData(url) // 返回一个 promise 对象

.catch(e => {

return downloadFallbackData(url) // 返回一个 promise 对象

})

.then(v => {

return processDataInWorker(v); // 返回一个 promise 对象

});

}

使用async和await重写上述函数。

async function getProcessedData(url) {

let v;

try {

v = await downloadData(url);

} catch (e) {

v = await downloadFallbackData(url);

}

return processDataInWorker(v);

}

以上就是关于“如何学习JS中的异步和Promise对象”的介绍了,感谢各位的阅读,如果大家想要了解更多相关的内容,小编每天都会为大家更新不同的知识。

(编辑:银川站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章