阅读源码,无意中看到这到一段,请教一下,这算是同步的还是异步的代码?

2022-03-24 08:15:06 +08:00
 yazoox

leran cli 的源代码 https://github.com/lerna/lerna/blob/main/core/command/index.js#L45

这个 command 的 constructor 里面,

  1. 这种执行方式,是同步的么?
      let chain = Promise.resolve();

      chain = chain.then(() => {
        this.project = new Project(argv.cwd);
      });
      chain = chain.then(() => this.configureEnvironment());
      chain = chain.then(() => this.configureOptions());
      chain = chain.then(() => this.configureProperties());
      chain = chain.then(() => this.configureLogging());
      chain = chain.then(() => this.runValidations());
      chain = chain.then(() => this.runPreparations());
      chain = chain.then(() => this.runCommand());
  1. 然后上面 1 中的代码,外面套了一层 let runner = new Promise((resolve, reject) => { ... } 后面继续 runer.then(...) 这个是同步还是异步?
  2. command 的 constructor 是同步还是异步?
  3. 该类 Command 的方法,runCommand()呢?
 runCommand() {
    return Promise.resolve()
      .then(() => this.initialize())
      .then((proceed) => {
        if (proceed !== false) {
          return this.execute();
        }
        // early exits set their own exitCode (if non-zero)
      });
  }

看得我好迷糊,也都没有添加 async 关键。

求指点。

谢谢!

5577 次点击
所在节点    JavaScript
18 条回复
chaoschick
2022-03-24 08:19:21 +08:00
异步
ZE3kr
2022-03-24 08:29:17 +08:00
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

Promise.prototype.then() 返回的是 Promise ,所以当然是异步了。和 chan = chain.then(async () => await Promise.all([this.configureEnvironment(), this.configureOptions(), ...])) 一样
ospider
2022-03-24 08:29:50 +08:00
async 就是 Promise 的语法糖啊,看到 Promise 基本就是异步。
MozzieW
2022-03-24 08:30:19 +08:00
把 chain 的赋值去掉,改写一下容易看。这是啥写法啊,脑筋急转弯呢
```
let chain = Promise.resolve()
.then(() => {
this.project = new Project(argv.cwd);
})
.then(() => this.configureEnvironment())
.then(() => this.configureOptions())
.then(() => this.configureProperties())
.then(() => this.configureLogging())
.then(() => this.runValidations())
.then(() => this.runPreparations())
.then(() => this.runCommand())
```
huanghui
2022-03-24 08:31:35 +08:00
了解一下 js 事件循环,宏任务和微任务
ZE3kr
2022-03-24 08:41:14 +08:00
刚才回复错了,两中写法不一样。上面那个代码效果**约**等于

chain = await chain.configureEnvironment()
chain = await chain.configureOptions()
...

是异步(指不会阻塞其他事件),但是每一步都是顺序执行的(指非并行)

Q: 然后上面 1 中的代码,外面套了一层 let runner = new Promise((resolve, reject) => { ... } 后面继续 runer.then(...) 这个是同步还是异步?

A: 取决于什么时候 call 的 resolve 。如果是 chan.then(resolve)那就顺序执行(指非并行)。但也是异步(指不会阻塞其他事件)

Q: command 的 constructor 是同步还是异步?

看你怎么定义异步同步了。我一般把返回的是 Promise 或者 async 函数叫做异步,无论函数内本身有没有调用异步

Q: 该类 Command 的方法,runCommand()呢?

你仔细看一下,是和 1 一样的,只是没有 chain 这个变量而已了。
eason1874
2022-03-24 08:50:54 +08:00
异步。这是链式写法,你在中间打印 chain 对象看一眼就知道了,是个还没完成的 Promise 对象
retrocode
2022-03-24 09:28:39 +08:00
异步的,这写法迷惑性太大,第一眼差点绕进去

```js

let a = Promise.resolve();
let b = a.then(() => {
this.project = new Project(argv.cwd);
});
let c = b.then(() => this.configureEnvironment());
let d = c.then(() => this.configureOptions());
let e = d.then(() => this.configureProperties());
let f = e.then(() => this.configureLogging());
let g = f.then(() => this.runValidations());
let h = g.then(() => this.runPreparations());
let i = h.then(() => this.runCommand());

```

脑补成这样会好理解些, 在转义下就是 6 楼的逻辑了
Lax
2022-03-24 09:36:12 +08:00
这是什么写法,把同步的链式操作拆成多个异步操作,仍然是链式操作?
KrisWuSkrSkr
2022-03-24 09:55:29 +08:00
promise 的同步是指什么样的。
acthtml
2022-03-24 10:00:45 +08:00
只要是 promise 就是异步,执行顺序不能保证,
promise 可通过.then 操作链顺序执行,可以利用 async/await 整个语法糖来顺序执行。

1. 等同于链式写法。
2 、3 同一个问题,整个方法体返回的是 promise 而已。promise 的执行顺序见上面。
Kasumi20
2022-03-24 10:12:14 +08:00
这些任务是同步的,搞不懂干嘛这样写,为了某一项出错后其它任务就停止了,然后用.catch 去处理错误?用异常不也一样?
en20
2022-03-24 10:44:19 +08:00
是异步,但会按顺序执行
xianyu191031
2022-03-24 10:48:18 +08:00
建议不要纠结同步异步,Event Loop 的机制过程熟读一下 这部分就很好理解了
libook
2022-03-24 12:35:10 +08:00
突然发现这个问题对于 JS 熟练开发者来说很容易理解,但解释起来可能会很复杂。
我写了又删,删了又写……

异步和同步,同时存在于两个维度,一个是 JS 执行维度,另一个是业务关系维度。

JS 执行上来说,同步执行就是按代码顺序执行,后写的表达式总会等待先写的表达式执行完再执行;
异步执行就是可以不按代码顺序执行,而是按需要执行,同时也不需要让后面的表达式等着它执行完成;
有的时候我们在异步执行的同时还需要一个异步操作等待另一个异步操作,JS 就提供了描述这种等待关系的机制(如 Promise.prototype.then() 和 await ),我习惯称之为“异步操作同步化”。

业务关系上来说,异步和同步是相对的,两个业务之间互相不依赖,就是异步关系,有依赖就是同步关系。

题主给的例子里代码很多,也有 Promise ,但其实核心还是回调函数,Promise 只是提供了一种隐式调用回调函数的机制而已,async 是 Promise 的语法糖,所以也是一样的。

这个思路基本就是,因为回调函数的函数体内容是按需执行的,外层的执行完成不依赖于回调函数内部执行完成,所以可以简单判断为回调函数外的部分以及回调函数本身的声明是同步执行的,回调函数内部程序相对外部作用域来说是异步执行的。

比如
chain = chain.then(() => {
this.project = new Project(argv.cwd);
});
可以拆成三部分,一部分是回调函数外的部分,即 chain = chain.then();
第二部分是回调函数本身的函数声明部分,即 ()=>{}
第三部分是回调函数的函数体内容部分,即 this.project = new Project(argv.cwd);

前两部分是按顺序执行的,是同步;第三部分是按需执行的,且前两部分不依赖这一部分的执行结果,是异步。
libook
2022-03-24 12:48:12 +08:00
@libook #15 我后半部分写的基本上是按照 JS 执行上来说的。
但从业务上来说,必须等 this.configureEnvironment() 执行完才能执行 this.configureOptions() ,这两个业务的关系是同步关系;而 chain = chain.then()不需要等 this.configureEnvironment()执行完成,所以这两个是异步关系;我们因为存在着异步关系所以需要使用 JS 异步语法来写,但为了同时满足业务上的同步关系需要使用 then 来描述等待关系。

也就是说 JS 执行维度和业务关系维度,异步和同步的辨析可能是不同的。
zhouyg
2022-03-24 17:19:15 +08:00
代码是异步执行,但在逻辑上是按顺序的
guanhui07
2022-03-24 18:35:31 +08:00
async 就是 Promise 的语法糖

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/842504

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX