如何将多个JS promises链接到组合布尔结果

L B*_*ker 1 javascript promise

我正在尝试在我的页面上验证各种元素及其数据.我有3种不同的方法来完成验证,其中一些方法可以进行ajax调用.每一个都返回一个布尔值的承诺.我想将结果合并为一个变量.我认为以下代码工作正常,但我的isValid变量似乎只捕获最后一个调用函数的值,saveCurrentSource().我如何才能isValid与saveSourceResponse()&& validateSource()&& 的结果相等saveCurrentSource()?

async validate() {
  return new Promise(resolve => {
    let isValid = this.saveSourceResponse()
      .then(saveSourceResponse => {
      console.log("saveSourceResponse",saveSourceResponse);
        return this.validateSource();
      }).then(validateSourceResponse => {
          console.log("validateSourceResponse",validateSourceResponse);
        return this.saveCurrentSource(validateSourceResponse);
      }).then(saveCurrentSourceResponse => {
          console.log("saveCurrentSourceResponse",saveCurrentSourceResponse);
        return saveCurrentSourceResponse;
      });
    resolve(isValid);
  });
}
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 5

首先,如果您使用的是async方法,则根本不需要直接访问承诺,只需使用await:

async validate() {
    return (
        await this.saveSourceResponse() &&
        await this.validateSource() &&
        await this.saveCurrentSource()
    );
}
Run Code Online (Sandbox Code Playgroud)

(我还在下面添加了一个并行版本.)

(我假设saveCurrentSource实际上并不需要你传递给它的论据.)

如果你没有想访问的承诺(例如,未使用async的validate),你会使用&&在每个then处理-而不会使用new Promise,因为没有理由:

validate() {
    return this.saveSourceResponse()
        .then(isValid => isValid && this.validateSource())
        .then(isValid => isValid && this.saveCurrentSource());
}
Run Code Online (Sandbox Code Playgroud)

如果我的假设saveCurrentSource不正确,我们会相应地调整它们:

async validate() {
    return (
        await this.saveSourceResponse() &&
        await this.validateSource() &&
        await this.saveCurrentSource(true) // `true` because this won't get executed
                                           // if `this.validateSource()` resolves
                                           // to `false`
    );
}
Run Code Online (Sandbox Code Playgroud)

要么:

validate() {
    return this.saveSourceResponse()
        .then(isValid => isValid && this.validateSource())
        .then(isValid => isValid && this.saveCurrentSource(true)); // `true` again,
                                                                   // see above
}
Run Code Online (Sandbox Code Playgroud)

正如Sescudero指出的那样,如果那些可以并行运行,我们应该并行运行它们:

async validate() {
    const results = await Promise.all([
        this.saveSourceResponse(),
        this.validateSource(),
        this.saveCurrentSource()
    ]);
    return results.every(valid => valid);
}
Run Code Online (Sandbox Code Playgroud)

...如果不使用,则非常相同async:

validate() {
    return Promise.all([
        this.saveSourceResponse(),
        this.validateSource(),
        this.saveCurrentSource()
    ]).then(results => results.every(valid => valid));
}
Run Code Online (Sandbox Code Playgroud)