Używam bluebird i widzę dwa sposoby przekształcania funkcji synchronicznych w obietnicę, ale nie widzę różnic między nimi. Wygląda na to, że ślad stosu jest nieco inny, więc nie są one tylko znakami alias
, prawda?
Więc jaki jest preferowany sposób?
Sposób A
function someFunction(someObject) {
return new Promise(function(resolve) {
someObject.resolved = true;
resolve(someObject);
});
}
Droga B
function someFunction(someObject) {
someObject.resolved = true;
return Promise.resolve(someObject);
}
javascript
promise
bluebird
Pipo
źródło
źródło
Promise.resolve
to tylko cukier.Odpowiedzi:
W przeciwieństwie do obu odpowiedzi w komentarzach - jest różnica.
Podczas
Promise.resolve(x);
jest w zasadzie taki sam jak
new Promise(function(r){ r(x); });
jest subtelność.
Funkcje zwracające obietnicę powinny generalnie mieć gwarancję, że nie powinny wyrzucać synchronicznie, ponieważ mogą wyrzucać asynchronicznie. Aby zapobiec nieoczekiwanym wynikom i warunkom wyścigu - rzuty są zwykle konwertowane na zwrócone odrzucenia.
Mając to na uwadze - kiedy specyfikacja została stworzona, obiecujący konstruktor jest bezpieczny.
A jeśli
someObject
takundefined
?Bluebird zauważył to i Petka dodał,
Promise.method
aby rozwiązać ten problem, abyś mógł nadal używać zwracanych wartości. Tak więc poprawny i najłatwiejszy sposób zapisania tego w Bluebird to w rzeczywistości żadne z nich - to jest:var someFunction = Promise.method(function someFunction(someObject){ someObject.resolved = true; return someObject; });
Promise.method zamieni rzuty na odrzucenia i wróci do rozstrzygnięć za Ciebie. Jest to najbardziej bezpieczny sposób, aby to zrobić, i asymiluje
then
ables poprzez zwracane wartości, więc zadziała, nawet jeślisomeObject
jest w rzeczywistości obietnicą.Ogólnie
Promise.resolve
jest używany do odlewania przedmiotów i obcych obietnic (dóbr) na obietnice. To jest jego przypadek użycia.źródło
Promise.resolve()
jest anty-wzorcem?Promise.resolve()
tworzy nową instancjęPromise
w taki sam sposób, jak przy użyciunew
? Jeśli nie,return Promise.resolve(yourCode)
byłby szybszy i unikał synchronicznych rzutów.Promise.coroutine
co jest jeszcze bardziej przydatne.Jest jeszcze jedna różnica nie wymieniona w powyższych odpowiedziach lub komentarzach:
Jeśli
someObject
jestPromise
,new Promise(resolve)
kosztowałoby dwa dodatkowe tiki.Porównaj dwa następujące fragmenty kodu:
const p = new Promise(resovle => setTimeout(resovle)); new Promise(resolve => resolve(p)).then(() => { console.log("tick 3"); }); p.then(() => { console.log("tick 1"); }).then(() => { console.log("tick 2"); });
const p = new Promise(resovle => setTimeout(resovle)); Promise.resolve(p).then(() => { console.log("tick 3"); }); p.then(() => { console.log("tick 1"); }).then(() => { console.log("tick 2"); });
Drugi fragment wypisuje najpierw „tick 3”. Czemu?
Jeśli wartość jest obietnicą,
Promise.resolve(value)
zwróci wartość dokładnie.Promise.resolve(value) === value
byłoby prawdą. zobacz MDNAle
new Promise(resolve => resolve(value))
zwróci nową obietnicę, która została zablokowana, aby spełnićvalue
obietnicę. Potrzeba dodatkowego jednego zaznaczenia, aby „zablokować się”.// something like: addToMicroTaskQueue(() => { p.then(() => { /* resolve newly promise */ }) // all subsequent .then on newly promise go on from here .then(() => { console.log("tick 3"); }); });
tick 1
.then
Wezwanie byłoby w pierwszej kolejności.Bibliografia:
źródło