js异步编程

js 异步编程#

js 采用单线程模式, 优点:安全/简单 缺点:耗时需等待

同步模式#

大多数任务都是同步执行,逐行执行

异步模式#

  • 开启过后立即执行下一个任务
  • 事件循环Event loop来监听调用栈和消息队列

回调函数#

所有异步编程方案的根基

Promise#

  • CommonJS 提出的
  • 一个对象
  • 初始 pending
  • promsie 的对象会率先进入队列,先执行同步的代码
const promise = new Promise(function(resolve, reject) {
resolve(100);
// reject(new Error('失败n'))
});
promise.then(
function(value) {
console.log(value); // 100
},
function(err) {
console.log(err);
}
);

Promise 的案例#

Promised 对象 then 方法会返回一个全新的 Promise 对象

function ajax(url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "json";
xhr.onload = function () {
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
});
}
ajax("/api/a.json").then(
function (res) {
console.log(res);
}).catch(err) {
console.log(err)
}

Promsie 静态方法#

Promise.resolve("foo").then(function(val) {
console.log(val);
});

Promise 并行执行#

等到多有任务结束才会结束,

return Promise.all([ajax("/api"), ajax("/api/user")]);

promise.race#

只等待一个任务结束

Promise.race([request]).then(value=>{
console.log(value)
}).catch(err){
console.log(err)
}

Promise 执行时序问题#

执行时序 / 宏任务 /微任务 与 setTimeout 相比 Promise 优先执行,即使 Promise 在 setTimeout 后面

Promise 回调是微任务执行,立即调用,而 setTimeout 为宏任务执行

Generator 异步方案#

生成器语法 yield 可暂停生成器

function* main() {
const user = yield ajax("/api");
}
const g = main();
const result = g.next();
result.value.then((data) => {
g.next(data);
});

递归生成器

function handleResult(result) {
if (result.done) return;
result.value.then(
(data) => {
handleResult(data);
},
(err) => {
g.throw(err);
}
);
}

Async/Await 语法糖#

语言层面标准语法