共计 1996 个字符,预计需要花费 5 分钟才能阅读完成。
异步是什么?
异步是绝对于同步而言的,同步就是一行一行代码执行上来,异步呢就是分成多个工作同时执行。
举个例子:
西游记中大闹五庄观一回里,童子大骂唐僧师徒是偷果子的秃贼,孙悟空气的脸涨得通红,但又不能当师父面发生,于是真身入迷,到园子里把人参果树推倒,没留一个果子,完事毫毛一收,趁着夜色解开门锁,带着师徒一行人逃跑了。
这里的猴子,本体还在挨骂受气呢,后果分身跑去铲果树了,这就是个异步的过程。
异步是怎么实现的?
javascript 不是单线程的吗,那么它是如何实现异步的呢?
如果你在加班的时候,外卖到了,你会怎么做呢?本人去拿,工作思路会被打断。像孙悟空一样分身,那不事实。好在公司不止一个人,咱们能够叫其余共事帮忙拿一下,拿到外卖后通知咱们一声,而后咱们就能够欢快的用餐了。
JS 也是如此,尽管它是单线程的,只能同时解决一件事,然而主线程能够发动一个异步申请,相应的工作线程就会接管这个申请并进行解决,等到工作线程的解决有了后果,浏览器就会告诉主线程,方才的申请曾经实现,后果曾经拿到了,能够执行回调函数,解决异步取得的后果。
如何编写异步代码?
最正当的形式是通过 Promise 对象。
举个例子,咱们来看看它是怎么用的。
上个月小舅子向我借了点钱,明天偶尔碰到他,我便问他什么时候能还钱,他说下个月发了工资就还我。我说不行啊,下个月我要出差。他说:这样吧,姐夫,你通知我,你打算用这笔钱做什么,我替你去做。尽管我示意狐疑,但也只能承受了,毕竟我还有别的事件要去做,不可能始终等着他变出钱来。
于是我跟他说:好吧。那下个月你间接把欠我的钱,交到我的老婆那里好了。小舅子痛快的许可了。
把下面的情景用代码示意,就像这样:
// Promise 对象
let 小舅子的承诺 = new Promise((许可的事件) => {setTimeout(() => {
let 工资 = 2000; // 发工资了
let 要还的钱 = 工资 * 0.5; // 拿出一半还账
许可的事件 (要还的钱); // 解决姐夫的委托
}, 30 * 100); // 30 天后...
});
// 回调函数
function 我的申请 (一笔钱) {console.log('把' + 一笔钱 + '上交给老婆');
}
// then 指定回调函数
小舅子的承诺.then(我的申请); // 小舅子许可了我的申请
// 3 秒后打印:把 1000 上交给老婆
async/await 是什么?
JS 的语法糖而已,能够让你从回调函数中解放出来。
还是以下面的情景为例,如果我打算拿这钱去做个按摩 … 像这种事相对不能和小舅子说,要是我老婆要是晓得了话,必定会把我活剥了。那就让小舅子把要还的钱间接打我银行卡里,我就等银行的到账告诉就行了。也不耽搁我的工作,又不必通知小舅子我的打算,而且我能够自在的安顿资金的用处。
写成代码的话就像这样:
// Promise 对象
let 小舅子的承诺 = new Promise((许可的事件) => {setTimeout(() => {
let 工资 = 2000; // 发工资了
let 要还的钱 = 工资 * 0.5; // 拿出一半还账
许可的事件 (要还的钱); // 解决姐夫的委托
}, 30 * 100); // 30 天后...
});
// 异步函数
async function 我的打算 () {
// 用了 await 委托就变成了:无需解决间接转账给我
let 一笔钱 = await 小舅子的承诺; // 期待小舅子转账
console.log('拿' + 一笔钱 + '去做个按摩');
};
// 调用异步函数
我的打算 ();
// 3 秒后打印:拿 1000 去做个按摩
两种写法有什么区别吗?
都是基于 Promise 对象,只不过一个用 then 办法指定回调函数,一个用 await 获取 resolve 的值(其实就是参数自身)。须要留神的是 await 须要写在异步函数中(思考下,为什么)。
来做个小练习,能够帮你了解这二者之间的区别。
function get(url, callback) {var req = new XMLHttpRequest();
req.open('GET', url, true);
req.onload = function () {if (req.readyState == 4 && req.status == 200) {callback(req.response);
}
}
req.send();}
var url = 'https://miao.baidu.com/';
get(url, function (html) {var re = new RegExp('<[^<>]+>', 'g');
var text = html.replace(re, "");
console.log(text);
});
// 在 miao.baidu.com 页面的控制台中执行
// 打印:Hello World
请参照下面的代码,用 Promise 对象封装一个 get 函数。
通过这个函数拜访 miao.baidu.com,并打印去除了所有 HTML 标签后的文本。
要求:应用 then 和 await 两种办法。