Node.js异步编程笔记

0 异步编程

异步编程和事件监听都是Nodejs特性。

1.Promise

promise对象实际是一个状态机,状态有 pending(进行中)、fullfill(完成)、reject(失败)。当状态改变时,会根据状态,交由 resolve 和 reject 处理。resolve 返回 value,reject 返回 err。

promise 对象同时提供 then() 去声明回调函数,参数为 resolve、reject。

链式调用用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var i = 0;
//函数返回promise
function sleep(ms) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('我执行好了');
i++;
if (i >= 2) reject(new Error('i>=2'));
else resolve(i);
}, ms);
})
}
sleep(1000).then(function (val1) {
console.log(val1);
return sleep(1000) // 返回给val2 继续回调
}).then(function (val2) {
console.log(val2);
return sleep(1000)
}).then(function (val3) {
console.log(val3);
return sleep(1000)
}).catch(function (err) {
console.log('出错啦:' + err.message);
})

2.async await

promise/then 回调函数之间传参非常麻烦。async/await 把异步写法变成了”同步”写法。async声明的函数会返回一个promise对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var i = 0;
function sleep(ms) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('我执行好了');
i++;
if (i >= 2) reject(new Error('i>=2'));
else resolve(i);
}, ms);
})
}
// 写法
(async() => {
var test = await sleep(1000);
console.log(test);
})()

await 必须要在声明了 async 函数里面,此时使用 await 会使函数阻塞,等待该 promise 对象 resolve 或 reject。但是这种阻塞几乎不会影响性能,因为它内部所有的阻塞都被封装在一个 Promise 对象中异步执行,这就是 await 必须用在 async 函数中的原因。