-1

let's say I have this generic function that makes an upsert in a realmjs database:

export const doAddLocalObject = async <T>(
  name: string,
  data: T
) => {
  // id must be informed by client
  if (!data._id) throw new Error(`Id not set for element ${name}`);
  //
  const realm = await getRealmBasedOnConfig();
  let result: T | undefined;
  realm.write(() => {
    result = realm.create<T>(name, data, UpdateMode.Modified).toJSON();
  });
  if (!result) {
    throw new Error(
      `Element ${name} with id ${data._id.toHexString()} was not added`
    );
  }
  return result;
};

The realm.open() method is async so that's why I need to do AWAIT and make this function also async. This is fine. But now I have some doubts about should be declared the function that calls this method. There are two ways. The first:

  function addCustomer(session: Session, customer: Customer): Promise<Customer> {
    checkAccess('user', session);
    return doAddLocalObject('customer', customer);
  }

And the second:

  async function addCustomer(session: Session, customer: Customer): Promise<Customer> {
    checkAccess('user', session);
    return await doAddLocalObject('customer', customer);
  }

Both return the same. Both seems to work fine. But is there any rule that says how this should be implemented? Is there any performance problem using some way from the other?

My bet is that the best option is (1) because I dont use the result object so there is no reason to await for the response. But I want to be sure.

Mariano L
  • 1,809
  • 4
  • 29
  • 51
  • "*The realm.open() method is async*" - you're not using that anywhere in the snippet you posted? Btw it looks like `realm.write` is asynchronous, but you're not properly (promisifying and) awaiting it. – Bergi Jun 30 '21 at 21:12
  • const realm = await getRealmBasedOnConfig(); do that part... is not important for my question tho.. and Realm.write executes synchronously – Mariano L Jun 30 '21 at 21:19

1 Answers1

1

There are two ways [to call the function]. Both return the same. Both seems to work fine.

Yes. return and return await are equivalent here.

However, notice that the first version is not declared as async, so when checkAccess throws an exception (and it looks like it's designed to do that), you would get an exception with the first version but a rejected promise with the second. Since an asynchronous function should never throw a synchronous exception but always return a promise (so that e.g. addCustomer(…).catch(…) works as expected), you probably should avoid the first version. You can however write

async function addCustomer(session: Session, customer: Customer): Promise<Customer> { /*
^^^^^ */
  checkAccess('user', session);
  return   doAddLocalObject('customer', customer);
//       ^
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375