w3schools then sincronas promises promesas funciones example await anidadas javascript promise rsvp.js

then - promise javascript example



La cadena de promesas continĂșa antes de que se resuelva la promesa interna (1)

La pregunta similar a Promesa se resuelve antes de que se haya resuelto la promesa interna, pero no puedo lograr que funcione sin excepción.

¡Cada vez que creo que entiendo las promesas, pruebo que estoy equivocado!

Tengo funciones que están escritas así

function getFileBinaryData () { var promise = new RSVP.Promise(function(resolve, reject){ var executorBody = { url: rootSite + sourceRelativeUrl + "/_api/web/GetFileByServerRelativeUrl(''" + fileUrl + "'')/$value", method: "GET", binaryStringResponseBody: true, success: function (fileData) { resolve(fileData.body); }, error: function (argument) { alert("could not get file binary body") } } sourceExecutor.executeAsync(executorBody); }); return promise; } function copyFileAction (fileBinaryData) { var promise = new RSVP.Promise(function(resolve, reject){ var executorBody = { url: rootSite + targetWebRelativeUrl + "/_api/web/GetFolderByServerRelativeUrl(''" + targetList + "'')/Files/Add(url=''" + fileName + "." + fileExt + "'', overwrite=true)", method: "POST", headers: { "Accept": "application/json; odata=verbose" }, contentType: "application/json;odata=verbose", binaryStringRequestBody: true, body: fileBinaryData, success: function (copyFileData) { resolve(); }, error: function (sender, args) { } } targetExecutor.executeAsync(executorBody); }); return promise; }

que trato de encadenar de esta manera

$.getScript("/_layouts/15/SP.RequestExecutor.js") .then(patchRequestExecutor) .then(function(){ sourceExecutor = new SP.RequestExecutor(sourceFullUrl); targetExecutor = new SP.RequestExecutor(targetList); }) .then(getFileInformation) .then(getFileBinaryData) .then(copyFileAction) .then(getTargetListItem) .then(updateTargetListItem) .catch(function (sender, args) { });

o así

$.getScript("/_layouts/15/SP.RequestExecutor.js") .then(patchRequestExecutor) .then(function(){ sourceExecutor = new SP.RequestExecutor(sourceFullUrl); targetExecutor = new SP.RequestExecutor(targetList); }) .then(function(){ return getFileInformation(); }) .then(function(){ return getFileBinaryData(); }) .then(function(binaryData){ return copyFileAction(binaryData) }) .then(function(){ return getTargetListItem(); }) .then(function(listItem){ return updateTargetListItem(listItem); });

El problema es que incluso si devuelvo nuevas promesas, la ejecución continúa por la cadena antes de que se resuelvan las promesas internas. ¿Cómo? ¿No debería esperar hasta que la solicitud asíncrona haya tenido éxito y se llame a resolve() en la devolución de llamada success ?


No has hecho nada malo aquí. Esto es culpa de jQuery, como muy a menudo 1 .

El problema es que jQuery no es compatible con Promises / A + (hasta v 3.0) y no puede adoptar promesas / thenable de otras implementaciones distintas a las suyas. Por lo tanto, cuando las devoluciones de llamada devuelven las promesas de RSVP, jQuery simplemente las trata como valores para cumplir, en lugar de esperarlas.
Podrías lanzar todas tus promesas a jQuery diferido y funcionaría, pero realmente no quieres eso. Para que el comportamiento estándar de Promise (ofrecido por RSVP) funcione, deberá evitar el error de JQuery. Esto puede hacerse fácilmente :

RSVP.Promise.resolve($.getScript("/_layouts/15/SP.RequestExecutor.js")) // ^^^^^^^^^^^^^^^ .then(patchRequestExecutor) .then(function(){ sourceExecutor = new SP.RequestExecutor(sourceFullUrl); targetExecutor = new SP.RequestExecutor(targetList); }) .then(getFileInformation) .then(getFileBinaryData) .then(copyFileAction) …