2017-02-14 18 views
44

Eksperymentuję ze słowem kluczowym await w pliku Node.js. Mam ten skrypt testowy:"Czekaj na nieoczekiwany identyfikator" na Node.js 7.5

"use strict"; 
function x() { 
    return new Promise(function(resolve, reject) { 
    setTimeout(function() { 
     resolve({a:42}); 
    },100); 
    }); 
} 
await x(); 

Ale kiedy go uruchomić w węźle uzyskać

await x(); 
    ^
SyntaxError: Unexpected identifier 

czy uruchomić go node lub node --harmony-async-await lub w node.js „repl” na moim Mac z Node.js 7.5 lub Node.js 8 (kompilacja nocna).

dziwne, ten sam kod działa w środowisku notebooka runkit javascript: https://runkit.com/glynnbird/58a2eb23aad2bb0014ea614b

Co robię źle?

+17

Możesz użyć 'await' tylko wewnątrz' async funkcji's. – Bergi

+1

Nie jestem pewien, czy możesz użyć funkcji 'await' poza funkcją' async', ale mogę się mylić. – nainy

Odpowiedz

67

Dzięki innym komentatorom i innym badaniom await można używać tylko w funkcji async, np.

async function x() { 
    var obj = await new Promise(function(resolve, reject) { 
    setTimeout(function() { 
     resolve({a:42}); 
    },100); 
    }); 
    return obj; 
} 

Mogłem wtedy użyć tej funkcji jako Promise, np.

x().then(console.log) 

lub w innej funkcji asynchronicznej.

Confusingly The node.js repl nie pozwalają zrobić

await x(); 

gdzie jako środowisko runkit notebook robi.

+3

Nie ma sensu deklarować 'x' jako' async'. Wystarczy mieć normalną funkcję i "zwrócić" obietnicę, jak pierwotnie, jest krótsza, bardziej wydajna i ma dokładnie taki sam wynik. – Bergi

+0

w haskell, nazywają to monadą asynchroniczną –

+0

Tak, callbacks są trudne. Async/Await również jest trochę skomplikowany. Musisz czekać na wszystko lub nic (coś takiego). Musimy więc jawnie wpisać asynchroniczne i oczekiwać na każde wywołanie funkcji, które z natury jest asynchroniczne. – zehelvion

23

Jak powiedzieli inni, nie można wywoływać funkcji "czekaj" poza funkcją asynchroniczną. Jednakże, aby ominąć to, można owinąć oczekujące x(); w wywołaniu funkcji asynchronicznej. To znaczy,

function x() { 
    return new Promise(function(resolve, reject) { 
    setTimeout(function() { 
     resolve({a:42}); 
    },100); 
    }); 
} 
//Shorter Version of x(): 
var x =() => new Promise((res,rej)=>setTimeout(() => res({a:42}),100)); 

(async()=>{ 
    try{ 
     var result = await x(); 
     console.log(result); 
    }catch(e){ 
     console.log(e) 
    } 
})(); 

Powinno to działać w węźle 7.5 lub nowszym. Działa również w obszarze chromowanych fragmentów kanarek.

9

tak jak zasugerowane przez innych oczekują będą działać wewnątrz async. Więc możesz użyć poniższego kodu, aby uniknąć używania:

async function callX() { 
    let x_value = await x(); 
    console.log(x_value); 
} 

callX(); 
Powiązane problemy