【问题标题】:Promise chain continues before inner promise is resolved在内部承诺解决之前承诺链继续
【发布时间】:2021-08-11 10:46:46
【问题描述】:

Promise resolve before inner promise resolved 类似的问题,但我仍然无法让它工作。

每当我认为我理解了承诺时,我就证明自己错了!

我有这样写的函数

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;
}

我尝试像这样链接

$.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) {

            });

或者像这样

$.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);
            });

但问题是,即使我返回新的 Promise,在解决任何内部 Promise 之前,执行仍会继续沿链向下执行。怎么会?难道不应该等到异步请求成功,在success回调中调用resolve()

【问题讨论】:

  • 您能否提供一个更小、更完整的 sn-p 来重现该问题?从这里我看不出你的代码有任何缺陷,应该可以工作。
  • 这一定是不是所有的异步函数都返回一个承诺。我会尝试修改代码以实现它!
  • 不要忘记在错误回调中reject。例如,您真的应该替换 alert
  • 绝对!它更像是一个调试助手,可以查看它可能失败的地方!

标签: javascript promise rsvp.js


【解决方案1】:

你在这里没有做错任何事。这是 jQuery 的错,as so often1.

问题在于 jQuery 与 Promises/A+ 不兼容(直到 v 3.0),并且无法从其他实现中采用 Promise/thenable 而不是它自己的。因此,当您的回调确实返回 RSVP 承诺时,jQuery 只是将它们视为要履行的值,而不是等待它们。
可以将你所有的promise 转换成一个jQuery deferred 并且它会起作用,但你真的不希望这样。要使标准的Promise 行为(由 RSVP 提供)起作用,您需要避免 jQuery 的错误 then。这个can easily be done

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)
    …

【讨论】:

  • 1):这也发生在 here 与原生承诺和 here 与 RSVP
  • Geebus,我从没想过会是因为这个,但它现在确实有效!非常感谢!
猜你喜欢
  • 2015-06-24
  • 1970-01-01
  • 2018-12-14
  • 1970-01-01
  • 1970-01-01
  • 2016-12-06
  • 2018-04-02
  • 2021-08-03
相关资源
最近更新 更多