-
At office hours, somebody reports that they export a notifier from a contract; when they consume it using I tried to reduce it to a smallish test case, but I'm struggling. The following doesn't seem to get any updates at all out of the iterator. It prints none of the newspaper headlines; just
The code I tried is: // @ts-check
// import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js';
import '@endo/init';
import {
makeNotifierKit,
makeAsyncIterableFromNotifier,
} from '@agoric/notifier';
// test('getting final result', async t => {
// });
const trial = async () => {
const newspaper = makeNotifierKit();
const publishNewsPaper = async () => {
newspaper.updater.updateState('Aug 1');
newspaper.updater.updateState('Aug 2');
newspaper.updater.updateState('Aug 3');
newspaper.updater.finish('Nov 2');
console.log('step3');
};
const readNewspaper = async () => {
const iter = makeAsyncIterableFromNotifier(newspaper.notifier);
console.log('step2');
for await (const headlines of iter) {
console.log(headlines);
}
};
console.log('stpe1');
await Promise.all([publishNewsPaper(), readNewspaper()]);
};
trial().catch(err => console.error(err)); cc @kriskowal |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
The dev pointed out that our dapps seem to rely on getting the final value: agoric-sdk/packages/inter-protocol/src/vaultFactory/vault.js Lines 364 to 371 in 6f72d00 or perhaps not? |
Beta Was this translation helpful? Give feedback.
-
Hello everybody 👋 I'm the dev from who asked this question. I think I made Dan's code work by simply waiting for one second after every state change. This worked because as far as I know notifier only pushes latest state and if a newer state arrives before it pushed state at hand, it pushes newest one and ignores the rest. The code looks like this; // @ts-check
import '@endo/init';
import {
makeNotifierKit,
makeAsyncIterableFromNotifier,
} from '@agoric/notifier';
const trial = async () => {
const newspaper = makeNotifierKit();
const publishNewsPaper = async () => {
newspaper.updater.updateState('Aug 1');
await new Promise(resolve => setTimeout(resolve, 1000));
newspaper.updater.updateState('Aug 2');
await new Promise(resolve => setTimeout(resolve, 1000));
newspaper.updater.updateState('Aug 3');
await new Promise(resolve => setTimeout(resolve, 1000));
newspaper.updater.finish('Nov 2');
console.log('step3');
};
const readNewspaper = async () => {
const iter = makeAsyncIterableFromNotifier(newspaper.notifier);
console.log('step2');
for await (const headlines of iter) {
console.log(headlines);
}
};
console.log('step1');
await Promise.all([publishNewsPaper(), readNewspaper()]);
};
trial().catch(err => console.error(err)); and the output
Basically yes, we did not get the
|
Beta Was this translation helpful? Give feedback.
-
The aync iterator is working as expected. JavaScript’s iterator protocols support a final value but const final = await for await (const medial of iterable) {} But, today, to see the final value, you have to implement the iterator protocol by hand: async function forAwaitEach(iterable, iterback) {
const iterator = iterator[Symbol.asyncIterator]();
try {
for (;;) {
const {done, value} = await iterator.next();
if (done) {
return value; // <- this is the final value that for loops don’t surface
}
await iterback(value);
}
} finally {
if (iterator.return) {
iterator.return();
}
}
}
const final = await forAwaitEach(iterator, medial => {}); |
Beta Was this translation helpful? Give feedback.
The aync iterator is working as expected. JavaScript’s iterator protocols support a final value but
for
loops do not surface it. There is a possibility thatfor
expressions will eventually be possible in the language, such that the following would surface that final value:But, today, to see the final value, you have to implement the iterator protocol by hand: