WebKit Bugzilla
Attachment 371556 Details for
Bug 198643
: async function resolution order
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
Test demonstrating differences in async / promise behavior
test2.html (text/html), 3.69 KB, created by
John Plaisted
on 2019-06-06 21:29:07 PDT
(
hide
)
Description:
Test demonstrating differences in async / promise behavior
Filename:
MIME Type:
Creator:
John Plaisted
Created:
2019-06-06 21:29:07 PDT
Size:
3.69 KB
patch
obsolete
><script> >async function testSafariFireFoxBug() { > let resolve; > const promise = new Promise((r) => resolve = r); > > let done = false; > async function helper() { > await promise; > done = true; > } > > helper(); > > // Queue: [] > resolve(); // Queue: [resolve P0 (then done)] > await 0; // Queue: [resolve P0 (then done), this await (then assert)] > > // I do not have any theories as to why this fails. > // Clearly this outer function `awaits` second, and the first is resolved already, and the testAsyncOrder > // below confirms that (on the browsers with the bug) the await order > // determines the callback order. These seem almost in conflict? > // Here the await AND resolve orders basically match, yet the continuation order > // is completely the opposite? > // Maybe it is because testAsyncOrder only uses promises, but above > // there's an `await 0`? > if (done) alert('async test passed'); > else alert('async test failed'); >} > >function testSafariFireFoxBug_promises() { > let resolve; > const promise = new Promise((r) => resolve = r); > > let done = false; > function helper() { > promise.then(() => { > done = true; > }); > } > > helper(); > > // Queue: [] > resolve(); // Queue: [resolve P0 (then done)] > return Promise.resolve().then(() => { // Queue: [resolve P0 (then done), > // this promise (then assert)] > > if (done) alert('promise test passed'); > else alert('promise test failed'); > }); >} > >class Resolver { > constructor() { > this.promise = new Promise(r => this.resolve = r); > } >} > >async function testAsyncOrder( > invertPromiseCreation, > invertCalls, > invertResolve >) { > let a, b; > if (invertPromiseCreation) { > b = new Resolver(); > a = new Resolver(); > } else { > a = new Resolver(); > b = new Resolver(); > } > const arr = []; > async function helper(r, i) { > await r.promise; > arr.push(i); > } > > const promises = []; > > if (invertCalls) { > promises.push(helper(b, 1)); > promises.push(helper(a, 0)); > } else { > promises.push(helper(a, 0)); > promises.push(helper(b, 1)); > } > > if (invertResolve) { > b.resolve(); > a.resolve(); > } else { > a.resolve(); > b.resolve(); > } > await Promise.all(promises); > return arr[0]; >} > >function testPromiseOrder( > invertPromiseCreation, > invertCalls, > invertResolve > ) { > let a, b; > if (invertPromiseCreation) { > b = new Resolver(); > a = new Resolver(); > } else { > a = new Resolver(); > b = new Resolver(); > } > const arr = []; > function helper(r, i) { > return r.promise.then(() => arr.push(i)); > } > > const promises = []; > > if (invertCalls) { > promises.push(helper(b, 1)); > promises.push(helper(a, 0)); > } else { > promises.push(helper(a, 0)); > promises.push(helper(b, 1)); > } > > if (invertResolve) { > b.resolve(); > a.resolve(); > } else { > a.resolve(); > b.resolve(); > } > return Promise.all(promises).then(() => arr[0]); > } > >async function test(fn, mode, kind) { > const noChanges = await fn(false, false, false); > const invertedPromiseCreation = await fn(true, false, false); > const invertedCalls = await fn(false, true, false); > const invertedResolve = await fn(false, false, true); > > if (noChanges !== invertedPromiseCreation) { > alert('Promise creation order affects ' + mode); > } > > if (noChanges !== invertedCalls) { > alert(kind + ' order affects ' + mode); > } > > if (noChanges !== invertedResolve) { > alert('resolve() order affects ' + mode); > } >} > >async function main() { > await testSafariFireFoxBug(); > await testSafariFireFoxBug_promises(); > await test(testAsyncOrder, 'async', 'await'); > await test(testPromiseOrder, 'promises', 'then()'); >} >main(); ></script>
<script> async function testSafariFireFoxBug() { let resolve; const promise = new Promise((r) => resolve = r); let done = false; async function helper() { await promise; done = true; } helper(); // Queue: [] resolve(); // Queue: [resolve P0 (then done)] await 0; // Queue: [resolve P0 (then done), this await (then assert)] // I do not have any theories as to why this fails. // Clearly this outer function `awaits` second, and the first is resolved already, and the testAsyncOrder // below confirms that (on the browsers with the bug) the await order // determines the callback order. These seem almost in conflict? // Here the await AND resolve orders basically match, yet the continuation order // is completely the opposite? // Maybe it is because testAsyncOrder only uses promises, but above // there's an `await 0`? if (done) alert('async test passed'); else alert('async test failed'); } function testSafariFireFoxBug_promises() { let resolve; const promise = new Promise((r) => resolve = r); let done = false; function helper() { promise.then(() => { done = true; }); } helper(); // Queue: [] resolve(); // Queue: [resolve P0 (then done)] return Promise.resolve().then(() => { // Queue: [resolve P0 (then done), // this promise (then assert)] if (done) alert('promise test passed'); else alert('promise test failed'); }); } class Resolver { constructor() { this.promise = new Promise(r => this.resolve = r); } } async function testAsyncOrder( invertPromiseCreation, invertCalls, invertResolve ) { let a, b; if (invertPromiseCreation) { b = new Resolver(); a = new Resolver(); } else { a = new Resolver(); b = new Resolver(); } const arr = []; async function helper(r, i) { await r.promise; arr.push(i); } const promises = []; if (invertCalls) { promises.push(helper(b, 1)); promises.push(helper(a, 0)); } else { promises.push(helper(a, 0)); promises.push(helper(b, 1)); } if (invertResolve) { b.resolve(); a.resolve(); } else { a.resolve(); b.resolve(); } await Promise.all(promises); return arr[0]; } function testPromiseOrder( invertPromiseCreation, invertCalls, invertResolve ) { let a, b; if (invertPromiseCreation) { b = new Resolver(); a = new Resolver(); } else { a = new Resolver(); b = new Resolver(); } const arr = []; function helper(r, i) { return r.promise.then(() => arr.push(i)); } const promises = []; if (invertCalls) { promises.push(helper(b, 1)); promises.push(helper(a, 0)); } else { promises.push(helper(a, 0)); promises.push(helper(b, 1)); } if (invertResolve) { b.resolve(); a.resolve(); } else { a.resolve(); b.resolve(); } return Promise.all(promises).then(() => arr[0]); } async function test(fn, mode, kind) { const noChanges = await fn(false, false, false); const invertedPromiseCreation = await fn(true, false, false); const invertedCalls = await fn(false, true, false); const invertedResolve = await fn(false, false, true); if (noChanges !== invertedPromiseCreation) { alert('Promise creation order affects ' + mode); } if (noChanges !== invertedCalls) { alert(kind + ' order affects ' + mode); } if (noChanges !== invertedResolve) { alert('resolve() order affects ' + mode); } } async function main() { await testSafariFireFoxBug(); await testSafariFireFoxBug_promises(); await test(testAsyncOrder, 'async', 'await'); await test(testPromiseOrder, 'promises', 'then()'); } main(); </script>
View Attachment As Raw
Actions:
View
Attachments on
bug 198643
: 371556