Altitude
2020-08-26T07:53:52+00:00
首先来看这段代码, 你认为输出是什么?
console.log('out 1');
new Promise((resolve) => {
setTimeout(resolve, 500);
}).then(() => {
console.log('inner');
});
console.log('out 2');
输出是:
out 1
out 2
inner
如果你想得到的是下面这个输出,那就是个非常复杂的问题.
out 1
inner
out 2
首先我理解nodejs中的回调函数性能非常好, 在做前端开发的时候特别合适. 因为前端代码中就是经常等待各种资源, 不过在nodejs, 做后端处理的时候, 这种回调函数很容易引发执行顺序的问题.
比如, 你需要提供一个对外开发的函数, 你需要等待拿到资源以后再返回方法, 但有些函数并没有提供同步版本(比如request模块), 你要怎么让一个异步的函数变成同步执行?
也许你想到了async和await. 首先给结论, async和await并没有解决这个问题, 看如下代码:
console.log('out 1');
async function f() {
await new Promise((resolve) => {
console.log('inner 1');
setTimeout(resolve, 500)
console.log('inner 2');
}).then(() => {
console.log('inner 3');
});
}
console.log('out 2');
f();
console.log('out 3');
你猜猜输出是啥?答案是:
out 1
out 2
inner 1
inner 2
out 3
inner 3
所以函数外部会直接运行, async和await保证了函数内的代码按顺序进行, 但对方法外的顺序无能为力.
也许你想到了使用sleep, 使用一个循环, 每次都去检查一个外部变量, 使用主动的方式去和异步方法保持同步. 但很可惜, 这行不通, 因为nodejs没有提供sleep这个方法. 你唯一的办法可能是用async和await来包装setTimeout方法, 使用曲线救国的方式来实现sleep.
总之, 这十分丑陋而且怪异, 我现在的办法是用deasync这个模块, 来让异步方法强行同步化. 至于它的底层原理, 我猜也是用async和await来包装setTimeout.
我对es6不满意的地方就是它发明了Promise, 但没有彻底异步的问题, 他的设计很先进, 但很多时候真的就是只想要一个最简单的 await result = request(url); 或者 sleep(100);
console.log('out 1');
new Promise((resolve) => {
setTimeout(resolve, 500);
}).then(() => {
console.log('inner');
});
console.log('out 2');
输出是:
out 1
out 2
inner
如果你想得到的是下面这个输出,那就是个非常复杂的问题.
out 1
inner
out 2
首先我理解nodejs中的回调函数性能非常好, 在做前端开发的时候特别合适. 因为前端代码中就是经常等待各种资源, 不过在nodejs, 做后端处理的时候, 这种回调函数很容易引发执行顺序的问题.
比如, 你需要提供一个对外开发的函数, 你需要等待拿到资源以后再返回方法, 但有些函数并没有提供同步版本(比如request模块), 你要怎么让一个异步的函数变成同步执行?
也许你想到了async和await. 首先给结论, async和await并没有解决这个问题, 看如下代码:
console.log('out 1');
async function f() {
await new Promise((resolve) => {
console.log('inner 1');
setTimeout(resolve, 500)
console.log('inner 2');
}).then(() => {
console.log('inner 3');
});
}
console.log('out 2');
f();
console.log('out 3');
你猜猜输出是啥?答案是:
out 1
out 2
inner 1
inner 2
out 3
inner 3
所以函数外部会直接运行, async和await保证了函数内的代码按顺序进行, 但对方法外的顺序无能为力.
也许你想到了使用sleep, 使用一个循环, 每次都去检查一个外部变量, 使用主动的方式去和异步方法保持同步. 但很可惜, 这行不通, 因为nodejs没有提供sleep这个方法. 你唯一的办法可能是用async和await来包装setTimeout方法, 使用曲线救国的方式来实现sleep.
总之, 这十分丑陋而且怪异, 我现在的办法是用deasync这个模块, 来让异步方法强行同步化. 至于它的底层原理, 我猜也是用async和await来包装setTimeout.
我对es6不满意的地方就是它发明了Promise, 但没有彻底异步的问题, 他的设计很先进, 但很多时候真的就是只想要一个最简单的 await result = request(url); 或者 sleep(100);