异步回调【code review】

Problem: callback hell (回调地狱)

指的是多层回调导致代码可读性变差。

特点:嵌套的多层括号。

  async saveAndUpdateStudyState(state: ProcessState): Promise<any> {
    return new Promise((resolve, reject) => {
      if (this.isValidToSave) {
        if (this.lastPatientExternalIdStashed && this.lastStudyIdStashed) {
          const queryStudyLocal: StudyForEditorLocalStashMeta = JSON.parse(
            this.localStoreService.query(this.lastStudyIdStashed)
          );
          const queryPatientLocal: PatientForEditorLocalStashMeta = JSON.parse(
            this.localStoreService.query(queryStudyLocal.data.data.patient_id)
          );
          console.log('in update', queryStudyLocal);
          upsertInRemoteDB(
            this.patientService,
            queryPatientLocal.data,
            (x: Patient[]) => {
              if (x && x.length > 0)
                this.localStoreService.update(x[0].id, {
                  ...queryPatientLocal,
                  data: x[0]
                });
              else reject('failed to query patient in remote DB');
              upsertInRemoteDB(
                this.studyService,
                toState(queryStudyLocal, state).data,
                (x: Study[]) => {
                  if (x && x.length > 0)
                    this.localStoreService.update(x[0].id, {
                      ...queryStudyLocal,
                      data: x[0]
                    });
                  else reject('failed to query study in remote DB');
                  console.log('on refetched study', x);
                  resolve(x[0]);
                }
              );
            }
          );
        }
      } else {
        console.log('not valid data');
        reject('not valid data');
      }
    });
  }

 

after fixed:

upsertInRemoteDB

async function upsertInRemoteDB<T extends { id: string }>(
  service: {
    updateMany: (...data: T[]) => Observable<T[]>;
    createMany: (...data: T[]) => Observable<T[]>;
    queryMany: (...data: string[]) => Observable<T[]>;
  },
  data: T
): Promise<any> {
  const queryResult = await service.queryMany(data.id).toPromise();
  return queryResult.length === 0
    ? await service.createMany(data).toPromise()
    : await service.updateMany(data).toPromise();
}

isValidToUpdateStudyState

  isValidToUpdateStudyState() {
    if (
      this.isValidToSave &&
      this.lastPatientExternalIdStashed &&
      this.lastStudyIdStashed
    ) {
      const queryStudyLocal: StudyForEditorLocalStashMeta = JSON.parse(
        this.localStoreService.query(this.lastStudyIdStashed)
      );
      const queryPatientLocal: PatientForEditorLocalStashMeta = JSON.parse(
        this.localStoreService.query(queryStudyLocal.data.data.patient_id)
      );
      console.log('in update', queryStudyLocal);
      if (queryPatientLocal && queryStudyLocal)
        return { localStudy: queryStudyLocal, localPatient: queryPatientLocal };
      else throw Error('fail to query study or patient in local');
    } else throw Error('not valid data');
  }

saveAndUpdateStudyState

  async saveAndUpdateStudyState(state: ProcessState): Promise<any> {
    const data: {
      localStudy: StudyForEditorLocalStashMeta;
      localPatient: PatientForEditorLocalStashMeta;
    } = this.isValidToUpdateStudyState();

    const remoteResultOfPatient = await upsertInRemoteDB(
      this.patientService,
      data.localPatient.data
    );
    if (remoteResultOfPatient) {
      const remoteResultOfStudy = await upsertInRemoteDB(
        this.studyService,
        toState(data.localStudy, state).data
      );
      if (remoteResultOfStudy) return remoteResultOfStudy;
      else throw Error('study upsert failed.');
    } else throw Error('patient upsert failed.');
  }

 

代码优化的方式:

1,同步异步代码分离,涉及到promise的地方用await关键字优化。

2,尽量不要混用几种异步方式,例如这里用promise那么upsertInRemoteDB函数也应该返回promise的形式。

 

异步的三种方式:

1,callback

definition:A callback is a function that is passed as an argument to another function and is executed after its parent function has completed.

回调函数就是一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数。这个过程就叫做回调。

Reference:https://baike.baidu.com/item/%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0/7545973?fr=aladdin

2,promise:

eg: ajax发送http请求

var ajax = ajaxGet('http://...');
ajax.ifSuccess(success)
    .ifFail(fail);

 

这种链式写法的好处在于,先统一执行AJAX逻辑,不关心如何处理结果,然后,根据结果是成功还是失败,在将来的某个时候调用success函数或fail函数。

古人云:“君子一诺千金”,这种“承诺将来会执行”的对象在JavaScript中称为Promise对象。

Reference:https://www.liaoxuefeng.com/wiki/1022910821149312/1023024413276544

3,Observable:

一种基于观察者模式的异步模型。

ReactiveX(Rx)是一种结合了observable模式、FP(functional programming)、iterator模式的一种优秀的开源实现。

Reference:http://reactivex.io/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值