#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 жалуется, что вы увеличиваете черновик и возвращаете значение.