2 | title: ES Array.fromAsync 3 | status: proposal 4 | stage: 3 (Conditional on Editor Review) 5 | location: https://github.com/js-choi/proposal-array-async-from 6 | copyright: false 7 | contributors: J. S. Choi 8 |9 | 10 |
This is the formal specification for a proposed `Array.fromAsync` factory method 13 | in JavaScript. It modifies the original ECMAScript specification with 15 | several new or revised clauses. See the proposal's 17 | explainer for the proposal's background, motivation, and usage examples.
18 |This proposal depends on the pull request tc39/ecma262#2942: “support built-in async functions”.
19 |IfAbruptCloseAsyncIterator is a shorthand for a sequence of algorithm steps that use an Iterator Record. An algorithm step of the form:
30 |means the same thing as:
34 |This section is a wholly new subsection of the original 58 | Properties of the Array Constructor clause, to be inserted before the Array.from 60 | clause.
61 |This async method performs the following steps when called:
64 |This method is an intentionally generic factory method; it does not require that its *this* value be the Array constructor. Therefore it can be transferred to or inherited by any other constructors that may be called with a single numeric argument.
133 || 129 | | Parallel awaiting | 130 |Sequential awaiting | 131 |
|---|---|---|
| Lazy iteration | 136 |Impossible | 137 |await Array.fromAsync(input) |
138 |
| Eager iteration | 141 |await Promise.all(Array.from(input)) |
142 | Useless | 143 |
| Status quo 575 | | With Array.fromAsync 576 | 577 | |
|---|---|
| 580 | 581 | ```js 582 | const all = require('it-all'); 583 | 584 | // Add the default assets to the repo. 585 | const results = await all( 586 | addAll( 587 | globSource(initDocsPath, { 588 | recursive: true, 589 | }), 590 | { preload: false }, 591 | ), 592 | ); 593 | const dir = results 594 | .filter(file => 595 | file.path === 'init-docs') 596 | .pop() 597 | print('to get started, enter:\n'); 598 | print( 599 | `\tjsipfs cat` + 600 | `/ipfs/${dir.cid}/readme\n`, 601 | ); 602 | ``` 603 | From [ipfs-core/src/runtime/init-assets-nodejs.js][]. 604 | 605 | | 606 | 607 | ```js 608 | // Add the default assets to the repo. 609 | const results = await Array.fromAsync( 610 | addAll( 611 | globSource(initDocsPath, { 612 | recursive: true, 613 | }), 614 | { preload: false }, 615 | ), 616 | ); 617 | const dir = results 618 | .filter(file => 619 | file.path === 'init-docs') 620 | .pop() 621 | print('to get started, enter:\n'); 622 | print( 623 | `\tjsipfs cat` + 624 | `/ipfs/${dir.cid}/readme\n`, 625 | ); 626 | ``` 627 | 628 | |
| 630 | 631 | ```js 632 | const all = require('it-all'); 633 | 634 | const results = await all( 635 | node.contentRouting 636 | .findProviders('a cid'), 637 | ); 638 | expect(results) 639 | .to.be.an('array') 640 | .with.lengthOf(1) 641 | .that.deep.equals([result]); 642 | ``` 643 | From [js-libp2p/test/content-routing/content-routing.node.js][]. 644 | 645 | | 646 | 647 | ```js 648 | const results = await Array.fromAsync( 649 | node.contentRouting 650 | .findProviders('a cid'), 651 | ); 652 | expect(results) 653 | .to.be.an('array') 654 | .with.lengthOf(1) 655 | .that.deep.equals([result]); 656 | ``` 657 | 658 | |
| 660 | 661 | ```js 662 | async function toArray(items) { 663 | const result = []; 664 | for await (const item of items) { 665 | result.push(item); 666 | } 667 | return result; 668 | } 669 | 670 | it('empty-pipeline', async () => { 671 | const pipeline = new Pipeline(); 672 | const result = await toArray( 673 | pipeline.execute( 674 | [ 1, 2, 3, 4, 5 ])); 675 | assert.deepStrictEqual( 676 | result, 677 | [ 1, 2, 3, 4, 5 ], 678 | ); 679 | }); 680 | ``` 681 | 682 | From [node-httptransfer/test/generator/pipeline.test.js][]. 683 | 684 | | 685 | 686 | ```js 687 | it('empty-pipeline', async () => { 688 | const pipeline = new Pipeline(); 689 | const result = await Array.fromAsync( 690 | pipeline.execute( 691 | [ 1, 2, 3, 4, 5 ])); 692 | assert.deepStrictEqual( 693 | result, 694 | [ 1, 2, 3, 4, 5 ], 695 | ); 696 | }); 697 | ``` 698 | 699 | |