Sumário
PrefácioVisão geral do ES71. Object.entries2. Object.values3. String.prototype.padEnd4. String.prototype.padStart5. Object.getOwnPropertyDescriptor6. Vírgulas à direita7. SharedArrayBuffer8. Atomics9. Funções assíncronasPrefácio
Olá, no passado, eu já considerei inovações no ES6 e agora é hora de desmontar o ES8, pois trouxe muitas coisas novas. Não considerei o ES7 (2016) separadamente, pois esse lançamento trouxe apenas 2 inovações. Este é o Array.prototype.includes () e o operador de exponenciação. Mas, ainda assim, antes de iniciar o ES8, vejamos as inovações do ES7.
Visão geral do ES7
O método includes () determina se a matriz contém um elemento específico, retornando verdadeiro ou falso, dependendo disso.
Array.prototype.includes(searchElement[, fromIndex = 0]) : Boolean
searchElement - O item a ser pesquisado.
fromIndex - A posição na matriz a partir da qual começar a procurar o elemento searchElement. Para valores negativos, a pesquisa é realizada começando com o índice array.length + fromIndex ascendente. O valor padrão é 0.
Exemplos [1, 2, 3].includes(2);
includ () pode ser aplicado a outros tipos de objetos (por exemplo, objetos do tipo array). Exemplo: usando o método includes () em um objeto de argumentos.
(function() { console.log([].includes.call(arguments, 'a'));
O operador de exponenciação (**) retorna uma potência com base a e um expoente natural b. Elevando a à potência de b.
a ** b
Exemplos 2 ** 3
1. Object.entries
Object.entries () retorna uma matriz cujos elementos são matrizes correspondentes à propriedade enumerada do par [chave, valor] encontrada diretamente no objeto. A ordem das propriedades é a mesma de quando você percorre as propriedades de um objeto manualmente.
Object.entries(obj) : Array
obj - Um objeto cujas propriedades enumeradas serão retornadas como uma matriz [chave, valor].
Object.entries () retorna as propriedades na mesma ordem que no loop for ... in (a diferença é que o for-in também lista as propriedades da cadeia de protótipos). A ordem dos elementos na matriz que Object.entries () retorna é independente de como o objeto é declarado. Se uma ordem específica for necessária, a matriz deverá ser classificada antes que o método seja chamado.
Exemplos var obj = { foo: "bar", baz: 42 }; console.log(Object.entries(obj));
Converter objeto em mapaO novo construtor Map () aceita a repetição de valores. Com Object.entries, você pode converter facilmente Objeto em Mapa. Isso é mais conciso do que usar uma matriz de 2 matrizes de elementos, mas as chaves podem ser apenas cadeias de caracteres.
var obj = { foo: "bar", baz: 42 }; var map = new Map(Object.entries(obj)); console.log(map);
Por que o valor de retorno de Object.entries () é uma matriz e não um iterador?
O caso de uso correspondente nesse caso é Object.keys () e não, por exemplo, Map.prototype.entries ().
Por que Object.entries () retorna apenas propriedades nativas enumeradas com chaves de seqüência de caracteres?
Novamente, isso é feito para corresponder a Object.keys (). Este método também ignora propriedades cujas chaves são caracteres. No final, pode haver um método Reflect.ownEntries () que retorna todas as suas próprias propriedades.
Consulte object.entries na
especificação oficial, bem como no
MDN Web Docs .
2. Object.values
Object.values () retorna uma matriz cujos elementos são os valores das propriedades enumeradas encontradas no objeto. A ordem é a mesma que se você percorresse o objeto manualmente.
Object.values(obj) : Array
obj - Um objeto cujos valores das propriedades enumeradas serão retornados.
O método Object.values () retorna uma matriz de valores das propriedades enumeradas do objeto na mesma ordem que o loop for ... in. A diferença entre um loop e um método é que o loop lista as propriedades da e da cadeia de protótipos.
Exemplos var obj = { foo: "bar", baz: 42 }; console.log(Object.values(obj));
A diferença entre Object.entries e Object.values () é que a primeira retorna uma matriz de matrizes contendo o nome e o valor da propriedade, enquanto a segunda retorna apenas uma matriz com o valor das propriedades.
Diferença de exemplo entre Object.values () e Object.entries () const object = { a: 'somestring', b: 42, c: false }; console.log(Object.values(object));
Consulte Object.values () na
especificação oficial, bem como no
MDN Web Docs .
3. String.prototype.padEnd
O método padEnd () completa a linha atual com a sequência especificada (eventualmente repetindo) para que a sequência resultante atinja o comprimento especificado. A adição é aplicada no final (à direita) da linha atual.
String.prototype.padEnd(maxLength [ , fillString ]) : String
maxLength - O comprimento da linha resultante após a linha atual ter sido preenchida. Se esse parâmetro for menor que o comprimento da linha atual, a linha atual será retornada como está.
fillString - Uma string para complementar a linha atual. Se essa linha for muito longa, será truncada e a sua esquerda mais será aplicada. "" (0x0020 ESPAÇO) é o valor padrão para este parâmetro.
Exemplos 'abc'.padEnd(10);
Os casos de uso para preencher cadeias de caracteres incluem:
- Adicionando um contador ou identificador a um nome ou URL de arquivo: 'file 001.txt'
- Alinhamento de saída do console: "Teste 001: ✓"
- Imprima números hexadecimais ou binários com um número fixo de dígitos: '0x00FF'
Consulte String.prototype.padEnd na
especificação oficial, bem como no
MDN Web Docs .
4. String.prototype.padStart
O método padStart () preenche a linha atual com outra linha (várias vezes, se necessário), para que a linha resultante atinja o comprimento especificado. O preenchimento é realizado no início (esquerda) da linha atual.
String.prototype.padStart(maxLength [, fillString]) : String
maxLength - o comprimento da linha de resumo após a conclusão da linha atual. Se o valor for menor que o comprimento da linha atual, a linha atual será retornada inalterada.
fillString - Uma string para preencher a linha atual. Se essa sequência for muito longa para o comprimento especificado, ela será truncada. O valor padrão é "" (0x0020 ESPAÇO).
Exemplos 'abc'.padStart(10);
Por que os métodos de preenchimento não são chamados padLeft e padRight?
Para idiomas bidirecionais ou da direita para a esquerda, os termos "esquerda" e "direita" não funcionam. Portanto, a nomeação de padStart e padEnd segue os nomes existentes, começando com beginWith e endsWith.
Consulte String.prototype.padStart na
especificação oficial, bem como no
MDN Web Docs .
5. Object.getOwnPropertyDescriptor
O método Object.getOwnPropertyDescriptor () retorna um descritor de propriedade para sua própria propriedade (ou seja, uma localizada diretamente no objeto e não recebida pela cadeia de protótipos) do objeto passado. Se a propriedade não existir, retornará indefinido.
Object.getOwnPropertyDescriptor(obj, prop) : Object
obj - O objeto no qual a propriedade é pesquisada.
prop - O nome da propriedade cuja descrição será retornada.
Este método permite visualizar a descrição exata da propriedade. Uma propriedade em JavaScript consiste em um nome de sequência e um descritor de propriedades.
Um descritor de propriedades é um registro com alguns dos seguintes atributos:
- valor - o valor associado à propriedade (apenas no descritor de dados).
- gravável - verdadeiro se o valor associado à propriedade puder ser alterado, caso contrário, falso (apenas no descritor de dados).
- get - Uma função que retorna o valor da propriedade ou indefinida se não houver essa função (apenas no descritor de acesso).
- set - Uma função que altera o valor de uma propriedade ou é indefinida se não houver essa função (apenas no descritor de acesso).
- configurable - true se o tipo de identificador desta propriedade puder ser alterado e se a propriedade puder ser removida do objeto que a contém, caso contrário, false.
- enumerable - true se esta propriedade estiver disponível ao listar as propriedades do objeto que a contém, caso contrário, false.
Exemplos obj = { get foo() { return 10; } }; console.log(Object.getOwnPropertyDescriptor(obj, 'foo'));
Casos de uso para Object.getOwnPropertyDescriptor ()
Primeiro caso de uso: copiar propriedades para um objeto
A partir do ES6, o JavaScript já possui um método de ferramenta para copiar propriedades: Object.assign (). No entanto, esse método usa operações simples de obter e definir para copiar uma propriedade cuja chave é a chave:
const value = source[key];
Isso significa que ele não copia corretamente propriedades com atributos diferentes dos especificados por padrão (métodos para obter, configurar, gravar etc.). O exemplo a seguir ilustra essa limitação. A fonte do objeto possui um instalador cuja chave é foo:
const source = { set foo(value) { console.log(value); } }; console.log(Object.getOwnPropertyDescriptor(source, 'foo'));
O uso de Object.assign () para copiar a propriedade foo no objeto de destino falha:
const target1 = {}; Object.assign(target1, source); console.log(Object.getOwnPropertyDescriptor(target1, 'foo'));
Felizmente, o uso de Object.getOwnPropertyDescriptors () junto com Object.defineProperties () funciona:
const target2 = {}; Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source)); console.log(Object.getOwnPropertyDescriptor(target2, 'foo'));
Segundo caso de uso: clonando objetos
A clonagem superficial é semelhante às propriedades de cópia; portanto, Object.getOwnPropertyDescriptors () também é uma boa opção aqui.
Desta vez, usamos Object.create (), que possui dois parâmetros:
O primeiro parâmetro especifica o protótipo do objeto retornado.
Um segundo parâmetro opcional é uma coleção de descritores de propriedades, semelhantes aos retornados por Object.getOwnPropertyDescriptors ().
const clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
Terceiro caso de uso: literais de objetos de plataforma cruzada com protótipos arbitrários.
A melhor maneira sintaticamente de usar um literal de objeto para criar um objeto com um protótipo arbitrário é usar a propriedade __proto__ especial:
const obj = { __proto__: prot, foo: 123, };
Infelizmente, esse recurso é garantido para estar presente apenas nos navegadores. A solução geral é Object.create () e atribuição:
const obj = Object.create(prot); obj.foo = 123;
Mas você também pode usar Object.getOwnPropertyDescriptors ():
const obj = Object.create( prot, Object.getOwnPropertyDescriptors({ foo: 123, }) );
Outra alternativa é Object.assign ():
const obj = Object.assign( Object.create(prot), { foo: 123, } );
Armadilha: copiando métodos usando super.
O método que super usa está fortemente ligado ao seu objeto inicial (o objeto em que está armazenado). Atualmente, não há como copiar ou mover esse método para outro objeto.
Consulte Object.getOwnPropertyDescriptor na
especificação oficial, bem como no
MDN Web Docs .
6. Vírgulas à direita
Vírgulas suspensas (vírgulas à direita) - podem ser úteis ao adicionar novos elementos, parâmetros ou propriedades ao código JavaScript. Se você deseja adicionar uma nova propriedade, basta adicionar uma nova linha sem alterar a anterior, se a vírgula suspensa já estiver sendo usada nela. Isso torna as diferenças no controle de versão mais limpas e as alterações de código podem ser menos problemáticas.
Pendurar vírgulas em literais
MatrizesJavaScript ignora vírgulas pendentes em matrizes:
var arr = [ 0, 1, 2, ]; console.log(arr);
Se mais de um ponto de oscilação for usado, serão criados furos. Uma matriz com "orifícios" é chamada esparsa (uma matriz densa não possui "orifícios"). Ao iterar uma matriz usando, por exemplo, Array.prototype.forEach () ou Array.prototype.map (), os buracos serão ignorados.
Os objetos var object = { foo: "bar", baz: "qwerty", age: 42, }; console.log(object);
Suspensão de vírgulas em funções
Definição de ParâmetrosAs seguintes definições de parâmetros de função são válidas e equivalentes entre si. Vírgulas pendentes não afetam a propriedade length de uma função ou seu objeto de argumentos.
function f(p) {} function f(p,) {} (p) => {}; (p,) => {};
Definição de métodoA vírgula suspensa também funciona com a definição de métodos para classes ou objetos.
class C { one(a,) {}, two(a, b,) {}, } var obj = { one(a,) {}, two(a, b,) {}, };
Chamada de funçãoAs seguintes chamadas de função são válidas e equivalentes entre si.
f(p); f(p,); Math.max(10, 20); Math.max(10, 20,);
Vírgulas suspensas inválidasDefinir parâmetros de função ou chamar uma função contendo apenas uma vírgula gerará um SyntaxError. Além disso, ao usar os parâmetros restantes, vírgulas suspensas não são permitidas.
function f(,) {}
Vírgulas suspensas na reestruturação
Vírgulas suspensas também podem ser usadas à esquerda ao usar tarefas destrutivas.
Mais uma vez, usando os parâmetros restantes, um SyntaxError será lançado.
var [a, ...b,] = [1, 2, 3];
JSON Dangling Vírgulas
Vírgulas
suspensas em um objeto são permitidas apenas no ECMAScript 5. Como o JSON é baseado na sintaxe JavaScript anterior ao ES5,
vírgulas suspensas não são permitidas
no JSON.Ambas as linhas lançam um SyntaxError
JSON.parse('[1, 2, 3, 4, ]'); JSON.parse('{"foo" : 1, }');
Por que as vírgulas suspensas são úteis?
Existem dois benefícios.
Em primeiro lugar, reorganizar elementos é mais fácil porque você não precisa adicionar ou remover vírgulas se o último elemento mudar de posição.
Em segundo lugar, ajuda os sistemas de controle de versão a acompanhar o que realmente mudou. Por exemplo, de:
[ 'Foo' ] : [ 'Foo', '' ]
faz com que a linha com 'foo' e a linha com 'bar' sejam marcadas como alteradas, embora a única alteração real seja adicionar a última linha.
Consulte Trails vírgulas no
MDN Web Docs .
7. SharedArrayBuffer
O objeto SharedArrayBuffer é usado para criar um buffer dividido de tamanho fixo para armazenar dados binários primitivos, semelhante ao objeto ArrayBuffer, mas, por outro lado, as instâncias SharedArrayBuffer podem ser usadas para criar uma exibição na memória compartilhada. SharedArrayBuffer não pode ser desconectado.
new SharedArrayBuffer(length) : Object
length - o tamanho, em bytes, para criar a matriz do buffer.
return - Um novo objeto SharedArrayBuffer do comprimento especificado. Seu conteúdo após a inicialização é 0.
O PostMessage e a clonagem estruturada são usados para dividir a memória usando um objeto SharedArrayBuffer entre um agente no cluster e outro (o agente pode ser o programa principal da página da Web ou um dos trabalhadores da Web).
O algoritmo de clonagem estruturada aceita SharedArrayBuffers e TypedArrays mapeados para SharedArrayBuffers. Nos dois casos, o objeto SharedArrayBuffer é passado ao destinatário, o que cria um novo objeto PrivateArrayBuffer privado dentro do agente de recebimento (o mesmo que para ArrayBuffer). No entanto, o bloco de dados compartilhados referenciado por ambos os objetos SharedArrayBuffer é o mesmo bloco de dados, e os efeitos de terceiros no bloco em um dos agentes acabam se tornando visíveis no outro agente.
var sab = new SharedArrayBuffer(1024); worker.postMessage(sab);
A memória compartilhada pode ser criada e alterada simultaneamente nos trabalhadores ou no encadeamento principal. Dependendo do sistema (CPU, SO, navegador), pode levar algum tempo até que as alterações sejam propagadas para todos os contextos. Para sincronização, são necessárias operações atômicas.
Buffers de matriz compartilhada é um bloco de construção primitivo para abstrações de paralelismo de nível superior. Eles permitem que você compartilhe os bytes de um objeto SharedArrayBuffer entre vários trabalhadores e o encadeamento principal (o buffer é compartilhado para acessar bytes, envolva-o em uma Matriz digitada). Esse tipo de troca tem duas vantagens:
Você pode trocar dados entre trabalhadores mais rapidamente.
A coordenação entre trabalhadores se torna mais fácil e rápida (em comparação com postMessage ()).
A implementação do trabalhador é a seguinte.
Primeiro, extraímos o buffer da matriz compartilhada que nos foi enviada e, em seguida, agrupamos em uma matriz digitada para que possamos usá-la localmente.
Propriedades e métodos de SharedArrayBuffer.SharedArrayBuffer.length - O comprimento do construtor SharedArrayBuffer cujo valor é 1.
SharedArrayBuffer.prototype - Permite propriedades adicionais para todos os objetos SharedArrayBuffer.
Instâncias SharedArrayBufferAs propriedadesSharedArrayBuffer.prototype.constructor - Define uma função que cria um protótipo de um objeto. O valor inicial é o construtor padrão SharedArrayBuffer interno.
SharedArrayBuffer.prototype.byteLength (somente leitura) - o tamanho da matriz em bytes. Isso é definido quando a matriz é criada e não pode ser alterada.
MétodosSharedArrayBuffer.prototype.slice () - Retorna um novo SharedArrayBuffer cujo conteúdo é uma cópia dos bytes desse SharedArrayBuffer desde o início, inclusive até o final, do exclusivo. Se o início ou o final forem negativos, isso se refere ao índice do final da matriz, não do início. Este método tem o mesmo algoritmo que Array.prototype.slice ().
sab.slice([begin, end]) : Object
begin - O índice zero no qual a extração começa. Você pode usar um índice negativo indicando o deslocamento do final da sequência. slice (-2) extrai os dois últimos elementos em uma sequência. Se o início não estiver definido, a fatia começará no índice 0.
Fim - O índice baseado em zero no qual a extração deve ser concluída.
Por exemplo, a fatia (1,4) recupera o segundo elemento através do quarto elemento (elementos com índices 1, 2 e 3). Você pode usar um índice negativo indicando o deslocamento do final da sequência. slice (2, -1) recupera o terceiro elemento através do penúltimo elemento na sequência. Se o fim for omitido, a fatia buscará no final da sequência (sab.byteLength).
Exemplos var sab = new SharedArrayBuffer(1024); sab.slice();
Consulte SharedArrayBuffer na
especificação oficial, bem como no
MDN Web Docs .
8. Atomics
O objeto Atomics fornece operações atômicas como métodos estáticos. Usado com um objeto SharedArrayBuffer.
As operações atômicas são instaladas no módulo Atomics. Ao contrário de outros objetos globais, o Atomics não é um construtor. Ele não pode ser usado com o novo operador ou para chamar um objeto Atomics como uma função. Todas as propriedades e métodos Atomics são estáticos (como um objeto Math, por exemplo).
Quando a memória é compartilhada, vários threads podem ler e gravar os mesmos dados na memória. As operações atômicas garantem que os valores esperados sejam gravados e lidos, e as operações concluídas antes da próxima operação começar seu trabalho, e elas não serão interrompidas.
As propriedades
Atomics [Symbol.toStringTag] - O valor dessa propriedade é Atomics.
Métodos
Operações atômicas- Atomics.add () - adiciona o valor apresentado ao atual na posição especificada na matriz. Retorna o valor anterior nesta posição.
- Atomics.and () - Calcula um AND bit a bit na posição especificada da matriz. Retorna o valor anterior nesta posição.
- Atomics.compareExchange () - Salva o valor apresentado na posição especificada da matriz, se for equivalente ao valor apresentado. Retorna o valor anterior.
- Atomics.exchange() — . .
- Atomics.load() — .
- Atomics.or() — OR . .
- Atomics.store() — . .
- Atomics.sub() — . .
- Atomics.xor() — XOR . .
Atomics.add() . , , .
Atomics.add(typedArray, index, value) : mixed
- typedArray — . Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array Uint32Array.
- index — typedArray value.
- value — .
- return — (typedArray[index]).
- TypeError, typedArray .
- TypeError, typedArray .
- RangeError, index typedArray.
var sab = new SharedArrayBuffer(1024); var ta = new Uint8Array(sab); Atomics.add(ta, 0, 12);
Atomics.add()
,
MDN Web Docs .
Wait notify
wait() wake() futexes («fast user-space mutex» — mutex ) Linux , true, .
Atomics.wait()
, -. «ok», «not-equal» «timed-out». , ( wait() ).
- Atomics.wait() — , -. «ok», «not-equal» «timed-out». , ( wait() ).
- Atomics.wake() — , . , .
- Atomics.isLockFree(size) — , . true, ( ). .
workers. , .
, , :
while (sharedArray [0] === 123);
sharedArray [0] ( sharedArray — , - ). :
const tmp = sharedArray [0]; while (tmp === 123);
, .
— :
, . , , :
workers, .
Atomics, .
:
.Atomics workers. , :
Atomics.load (TypedArray <T>, index) : T Atomics.store (TypedArray <T>, index, value: T) : T
, , Atomics (, ) , . , , Atomics.
, , Atomics ( sharedArray):
:
.
while , Atomics , : Atomics.wait (Int32Array, index, value, timeout) Atomics.wake (Int32Array, index, count).
:
atomic operationsAtomics , . Por exemplo:
Atomics.add (TypedArray <T>, index, value) : T
, : index += value;
c .
— (): — , .
«Tear-Free Reads» , , :
- , Typed Arrays ( DataViews).
- : sharedArray.byteOffset% sharedArray.BYTES_PER_ELEMENT === 0
- .
, , :
- Um ou mais DateViews;
- Há uma ou mais matrizes digitadas não alinhadas;
- Matrizes digitadas com diferentes tamanhos de elementos;
Para evitar uma lacuna nos valores nesses casos, use Atomics ou sync.Buffers de matriz compartilhada nos usos
Shared Array Buffers JavaScript « ». JavaScript « »: , . , , , .
Shared Array Buffers (RTC): , , . , RTC: Shared Array Buffers, .
, RTC. await.
Shared Array Buffers emscripten pthreads asm.js. emscripten:
[En] [Shared Array Buffers allow] Emscripten applications to share the main memory heap between web workers. This along with primitives for low level atomics and futex support enables Emscripten to implement support for the Pthreads (POSIX threads) API.
[Ru] [Shared Array Buffers ] Emscripten -. futex Emscripten API Pthreads ( POSIX).
C C ++ asm.js.
, WebAssembly. , web workers , , WebAssembly . , WebAssembly.
,
( 32 ). , — . , , :
- TextEncoder TextDecoder: Uint8Array, .
- stringview.js: , . .
- FlatJS: JavaScript (, ) (ArrayBuffer SharedArrayBuffer). JavaScript + FlatJS JavaScript. JavaScript (TypeScript . .) .
- TurboScript: JavaScript- . asm.js WebAssembly.
, , — — . , .
, Shared Array?. ( "
A Taste of JavaScript's New Parallel Primitives ”», , web workers. 4 web workers , , , , 6,9 (1 web worker) 25,4 (4 web workers). web workers , .
, , .
Shared Array Buffers :
JavaScript, :
Atomics Object
,
MDN Web Docs .
9. Async functions
Async function AsyncFunction constructor
AsyncFunction async function. JavaScript AsyncFunction.
, AsyncFunction . , .
Object.getPrototypeOf(async function(){}).constructor
new AsyncFunction([arg1[, arg2[, ...argN]],] functionBody)
arg1, arg2,… argN — , . , JavaScript , ; , «x», «theValue», «a,b».
functionBody — , JavaScript.
async function, AsyncFunction constructor , . , async function expression , .
, , , .
AsyncFunction constructor ( new) , .
async functions AsyncFunction constructor, ; . , , AsyncFunction constructor. eval async function.
async function AsyncFunction constructor
function resolveAfter2Seconds(x) { return new Promise(resolve => { setTimeout(() => { resolve(x); }, 2000); }); } var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor var a = new AsyncFunction('a', 'b', 'return await resolveAfter2Seconds(a) + await resolveAfter2Seconds(b);'); a(10, 20).then(v => { console.log(v);
async function
async function , AsyncFunction. async-, async function.
async function name([param[, param[, ... param]]]) {
name — .
param — , .
statements — , .
async Promise. , Promise , . async , Promise (throws) .
async await, async Promise, async .
await . SyntaxError.
async/await promises Promises. Promises callback-, async/await promises.
Exemplo function resolveAfter2Seconds(x) { return new Promise(resolve => { setTimeout(() => { resolve(x); }, 2000); }); } async function add1(x) { const a = await resolveAfter2Seconds(20); const b = await resolveAfter2Seconds(30); return x + a + b; } add1(10).then(v => { console.log(v);
?
JS- .js , . , . .
, JS — , . , , , , . , . (You-Dont-Know-JS/async & performance, Jake Archibald).
? console.log() , .
«» , :
ajax( "http://some.url.1", function myCallbackFunction(data){ console.log( data );
.
3 getUser, getPosts, getComments.
const { getUser, getPosts, getComments } = require('./db'); getUser(1, (error, user) => { if(error) return console.error(error); getPosts(user.id, (error, posts) => { if(error) return console.error(error); getComments(posts[0].id, (error, comment) => { if(error) return console.error(error); console.log(comments); }); }); });
, .
Callback Hell . , () , .
Promise (
, . . .
getUser(1) .then(user => getPosts(user,id)) .then(posts => getComments(posts[0].id)) .then(comments => console.log(comments)) .catch(error => console.error(error));
Promise Generators (
. , Promise, — , . try...catch. — Promise , . ,
co . .
co(function* () { try { let user = yield getUser(1); let posts = yield getPosts(user.id); let comments = yield getComments(posts[0].id); console.log(comments); } catch (error) { console.log(error); } }); function co(generator) { const iterator = generator(); return new Promise((resolve, reject) => { function run(prev) { const { value, done } = iterator.next(prev); if (done) resolve(value); else if (value instanceof Promise) value.then(run, reject); else run(value); } run(); }); }
.
(Calback functions) — , .
(Promises) — , .
(Generators) — , , .
(Promises) (Generators), , .
, , :
function getUser(id) { return { id: 1 }; } let user = getUser(1); console.log(user);
( async), Promise id.
async function getUser(id) { return { id: 1 }; } let user = getUser(1); console.log(user);
, , Promis ( Promis ). , .
then().
async function getUser(id) { return { id: 1 }; } getUser(1) .then(user => console.log(user));
await .
( HTTP .
fetch(`https://jsonplaceholder.typicode.com/users/1`) .then(data => data.json()) .then(data => console.log(data));
É assim que o código assíncrono se parece com o Promise.Mas podemos escrever código assíncrono como síncrono se usarmos funções assíncronas. async function sendRequest() { let response= await fetch(`https://jsonplaceholder.typicode.com/users/1`); return response.json(); } async function main() { var a = await sendRequest(); console.log(a); } main();
A única coisa que não gosto é que o operador assíncrono possa ser usado apenas em funções assíncronas. Caso contrário, eu não precisaria usar a função main (). Obviamente, você também pode usar o método then (), mas o código não parecerá mais assíncrono. async function sendRequest() { let response= await fetch(`https://jsonplaceholder.typicode.com/users/1`); return response.json(); } sendRequest() .then((data) => console.log(data));
fetch(). await, : fetch() response. : fetch() .
Promise async function
await , .
try...catch.
async function sendRequest() { let response = await fetch(`https://jsonplaceholder.typicode.com/users/1`); try { throw new Error("Unexpected error"); return response.json(); } catch(error) { console.log(error);
…
Async Function Definitions
,
MDN Web Docs .