跳转至

异步计算

https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/

  • 同步:阻塞
  • 异步:非阻塞

setTimeOutsetInterval

setTimeOut 延迟几秒钟后再执行代码:

console.log('A');
setTimeout(() => {console.log('B');}, 1000);  // 延迟 1000 毫秒
console.log('C');

结果是

A
C
B

而且 B 是过一会才出现的。

setInterval 很像,只不过在第一个延迟执行之后,每隔一会儿还会执行以下。

注意异步函数会在该 context 执行完了再执行:

let a = setTimeout(() => console.log('A'), 0);
let b = 3000000000;
while (b >= 0) {
  b--;
}
console.log('B');

先输出 B 再输出 A。

Promise

传统用 callback 的异步函数 loadFileAsync(path, successCallback, failureCallback),会在函数结束的时候调用 callback。

更现代的用 Promise 的异步函数会返回一个 Promise:

const promise = loadFileAsyncPromise(path);
promise.then(successCallback, failureCallback);

// 或者简写为
loadFileAsyncPromise(path).then(successCallback, failureCallback);

可以链式调用。

// 可以链式调用
loadFileAsyncPromise(path).then(successCallback, failureCallback).then(successCallback1, failureCallback1);

// 更详细灵活的链式调用
const promise1 = f();
const promise2 = promise1.then(callback);
const promise3 = promise2.then(callback);

// 用 catch 和直接在 then 里面是等价的
f().then(successCallback).catch(failureCallback);
f().then(successCallback, failureCallback);

// 这两个也是等价的,then 里面的 successCallback 可以 null
f().then(null, failureCallback);
f().catch(failureCallback);

// catch 之后还能继续 then
f().then(successCallback).catch(failureCallback).then(successCallback1);

整个链可以只有一个 failureCallback(无论在 then 还是在 catch 中),出现 reject 之后会一直向下寻找第一个 failureCallbackonReject),就像是整个 try 只有一个 catch 一样。

Promise 的状态

async/await 语法糖

进阶

Promise 拒绝事件