w3schools una sincronas promises promesas promesa incluir hacer funciones encadenamiento como asincronia javascript promise es6-promise

javascript - una - promesas typescript



Resolver Promesa de Javascript fuera del alcance de la funciĆ³n (7)

Me gustó la respuesta de @JonJaques, pero quería dar un paso más.

Si enlaza then y catch el objeto Deferred , entonces implementa completamente la Promise API y puede tratarlo como una promesa y await .

class DeferredPromise { constructor() { this._promise = new Promise((resolve, reject) => { // assign the resolve and reject functions to `this` // making them usable on the class instance this.resolve = resolve; this.reject = reject; }); // bind `then` and `catch` to implement the same interface as Promise this.then = this._promise.then.bind(this._promise); this.catch = this._promise.catch.bind(this._promise); this[Symbol.toStringTag] = ''Promise''; } } const deferred = new DeferredPromise(); console.log(''waiting 2 seconds...''); setTimeout(() => { deferred.resolve(''whoa!''); }, 2000); async function someAsyncFunction() { const value = await deferred; console.log(value); } someAsyncFunction();

He estado usando ES6 Promise.

Ordinariamente, una Promesa se construye y usa así

new Promise(function(resolve, reject){ if (someCondition){ resolve(); } else { reject(); } });

Pero he estado haciendo algo como a continuación para llevar la resolución al exterior por el bien de la flexibilidad.

var outsideResolve; var outsideReject; new Promise(function(resolve, reject) { outsideResolve = resolve; outsideReject = reject; });

Y después

onClick = function(){ outsideResolve(); }

Esto funciona bien, pero ¿hay una manera más fácil de hacer esto? Si no, ¿es esta una buena práctica?


No, no hay otra manera de hacerlo, lo único que puedo decir es que este caso de uso no es muy común. Como dijo Félix en el comentario, lo que hagas funcionará consistentemente.

Vale la pena mencionar que la razón por la que el constructor de promesas se comporta de esta manera es seguridad: si una excepción que no anticipó ocurre mientras su código se ejecuta dentro del constructor de promesa, se convertirá en un rechazo, esta forma de lanzar seguridad, convirtiendo errores lanzados en los rechazos son importantes y ayudan a mantener un código predecible.

Por este motivo de seguridad, el constructor de la promesa fue elegido por sobre aplazado (que es una forma alternativa de construcción prometedora que permite lo que estás haciendo) - en cuanto a las mejores prácticas - pasaría el elemento y usaría el constructor de la promesa:

var p = new Promise(function(resolve, reject){ this.onclick = resolve; }.bind(this));

Por esta razón, siempre que pueda usar el constructor de promesa sobre la exportación de las funciones, le recomiendo que lo use. Siempre que pueda evitar ambos, evite ambos y la cadena.

Tenga en cuenta que nunca debe usar el constructor de promesa para cosas como if(condition) , el primer ejemplo podría escribirse como:

var p = Promise[(someCondition)?"resolve":"reject"]();


Nuestra solución fue utilizar cierres para almacenar las funciones de resolución / rechazo y, además, adjuntar una función para extender la promesa en sí.

Aquí está el patrón:

function getPromise() { var _resolve, _reject; var promise = new Promise((resolve, reject) => { _reject = reject; _resolve = resolve; }); promise.resolve_ex = (value) => { _resolve(value); }; promise.reject_ex = (value) => { _reject(value); }; return promise; }

Y usándolo:

var promise = getPromise(); promise.then(value => { console.info(''The promise has been fulfilled: '' + value); }); promise.resolve_ex(''hello''); // or the reject version //promise.reject_ex(''goodbye'');


Un método auxiliar aliviaría esta sobrecarga adicional y le daría la misma sensación de jQuery.

function Deferred() { let resolve; let reject; const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); return { promise, resolve, reject }; }

El uso sería

const { promise, resolve, reject } = Deferred(); displayConfirmationDialog({ confirm: resolve, cancel: reject }); return promise;

Que es similar a jQuery

const dfd = $.Deferred(); displayConfirmationDialog({ confirm: dfd.resolve, cancel: dfd.reject }); return dfd.promise();

Aunque, en un caso de uso, esta sintaxis simple y nativa está bien

return new Promise((resolve, reject) => { displayConfirmationDialog({ confirm: resolve, cancel: reject }); });


Un poco tarde para la fiesta aquí, pero otra forma de hacerlo sería usar un objeto Deferred . Básicamente tiene la misma cantidad de texto estándar, pero es útil si desea pasarlos y posiblemente resolverlos fuera de su definición.

Implementación ingenua:

class Deferred { constructor() { this.promise = new Promise((resolve, reject)=> { this.reject = reject this.resolve = resolve }) } } function asyncAction() { var dfd = new Deferred() setTimeout(()=> { dfd.resolve(42) }, 500) return dfd.promise } asyncAction().then(result => { console.log(result) // 42 })

Versión ES5:

function Deferred() { var self = this; this.promise = new Promise(function(resolve, reject) { self.reject = reject self.resolve = resolve }) } function asyncAction() { var dfd = new Deferred() setTimeout(function() { dfd.resolve(42) }, 500) return dfd.promise } asyncAction().then(function(result) { console.log(result) // 42 })


Una solución que surgió en 2015 para mi marco. Llamé a este tipo de promesas Tarea

function createPromise(handler){ var _resolve, _reject; var promise = new Promise(function(resolve, reject){ _resolve = resolve; _reject = reject; handler(resolve, reject); }) promise.resolve = _resolve; promise.reject = _reject; return promise; } var promise = createPromise() promise.then(function(data){ alert(data) }) promise.resolve(200) // resolve from outside


sencillo:

var promiseResolve, promiseReject; var promise = new Promise(function(resolve, reject){ promiseResolve = resolve; promiseReject = reject; }); promiseResolve();