Как выполнить изменения в черновом объекте с помощью Immer.js после того, как обещание будет выполнено без использования асинхронного/ожидания

#javascript #async-await #es6-promise #immer.js

Вопрос:

Я пытаюсь внести изменения в черновик объекта из Immer, которые зависят от разрешения обещания. Я понимаю, как это сделать с async помощью / await синтаксиса (см. Ниже)

 import produce from 'immer';

Promise.resolve({ eggs: 0 }).then(
  produce(async (eggCounter) => { const n = (await 5); eggCounter.eggs  = n; })
).then(console.log)
 

но когда я пытаюсь перевести это в использование явного Promise API, это не работает:

 import produce from 'immer';

Promise.resolve({ eggs: 0 }).then(
  produce((eggCounter) => { Promise.resolve(5).then((n) => eggCounter.eggs  = n) })
).then(console.log)
 

Вышесказанное приводит к ошибке Uncaught (in promise) TypeError: illegal operation attempted on a revoked proxy .

Как я могу изменить второй образец, чтобы он был (в достаточной степени) эквивалентен первому?

Комментарии:

1. Какой у тебя await номер?

2. Это просто пример. В реальной ситуации это обещание, исходящее от API.

Ответ №1:

Просто верните обещание для produce функции обратного вызова:

Встроенная версия

 Promise.resolve({ eggs: 0 }).then(
  produce((eggCounter) => Promise.resolve(5).then((n) => { eggCounter.eggs  = n; }))
).then(console.log)
 

Ясная версия

 Promise.resolve({ eggs: 0 }).then(
  produce((eggCounter) => {
    return Promise.resolve(5).then((n) => {
      eggCounter.eggs  = n;
    });
  })
).then(console.log);
 

Комментарии:

1. Это правильно, хотя я упустил еще одну важную деталь: функция, переданная then вызову внутри produce обратного вызова, не должна возвращать значение (в противном случае immer жалуется, что вы увеличиваете черновик и возвращаете значение.