j0h*_*4r5 3 javascript promise
我有一个类方法,该方法将类中的其他方法链接在一起,并在类的另一个实例上调用一个方法:
class Thing {
doSomething(nextThing) {
return new Promise((resolve) =>
this.initialize()
.then(() => this.doA())
.then(() => {
nextThing.initialize(); // call initialize() on another instance
return this.doB();
})
.then(() => this.doC())
.then(resolve)
);
}
initialize() {
return new Promise((resolve) => {
// take a long time to do something
// ...
// ...
resolve();
});
}
doA() { return new Promise((resolve) => resolve()); }
doB() { return new Promise((resolve) => resolve()); }
doC() { return new Promise((resolve) => resolve()); }
}
const thing1 = new Thing();
const thing2 = new Thing();
thing1.doSomething(thing2);
Run Code Online (Sandbox Code Playgroud)
但是,在另一个类实例上调用该函数会锁定链的流程。this.doB()并且nextThing.initialize()会同时运行(根据需要),但this.doC()要等到nextThing.initialize()解决后才能运行。
什么是正确的方式来确保此流程按预期进行,nextThing.initialize()并this.doB()同时开始,并this.doC()在this.doB()解决后立即开始?这没关系,如果nextThing.initialize()结算后this.doC()。
当您执行此结构时:
return new Promise(resolve => {
// run some long synchronous piece of code
resolve(...);
});
Run Code Online (Sandbox Code Playgroud)
这是发生了什么。
resolve(...)来解决以前创建的承诺.then()根据先前的promise调用处理程序。因此,promise会同步调用执行程序回调。它不允许您“在后台运行任何内容”。Javascript仍然是单线程的。
您不能使用诺言将同步代码转换为异步代码。您可以使用一些promise技术来更改代码运行的时间安排,但是Javascript中的同步代码仍然是同步的,而Javascript中的阻塞代码无论何时运行。
Promise纯粹是一个通知系统,用于在其他操作告诉诺言现在已解决或被拒绝时通知您。它们不会神奇地将同步代码转换为异步代码。
因此,最重要的是,您不能使用promise采取同步的,长时间运行的initialize()功能,并以某种方式使其成为非阻塞或异步的。
用nextThing.initialize()和this.doB()同时启动的方式来确保按预期方式进行流动的正确方法是,
如果nextThing.initialize()是同步且阻塞的,则它不能与任何事物同时运行。node.js运行您的Javascript单线程。一次运行一个Javascript。承诺不能改变这一点。
并在this.doB()解析后立即启动this.doC()
由于this.doB()并且this.doC()两者都返回了Promise,因此您将Promise与链接的.then()处理程序链接在一起以对这些操作进行排序。您的代码似乎已经做到了。
有关将当前运行的同步代码卸载到当前node.js单个Javascript线程之外的选项的信息,请参见以下其他答案:
仅供参考,也许这只是伪代码,但是从来没有理由这样做:
return new Promise((resolve) => resolve());
Run Code Online (Sandbox Code Playgroud)
您可以改为:
return Promise.resolve();.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
535 次 |
| 最近记录: |