乐趣区

关于javascript:简单理解-Javascript-中的异步

异步是什么?

异步是绝对于同步而言的,同步就是一行一行代码执行上来,异步呢就是分成多个工作同时执行。

举个例子:

西游记中大闹五庄观一回里,童子大骂唐僧师徒是偷果子的秃贼,孙悟空气的脸涨得通红,但又不能当师父面发生,于是真身入迷,到园子里把人参果树推倒,没留一个果子,完事毫毛一收,趁着夜色解开门锁,带着师徒一行人逃跑了。

这里的猴子,本体还在挨骂受气呢,后果分身跑去铲果树了,这就是个异步的过程。

异步是怎么实现的?

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 两种办法。

退出移动版