本文介绍了在内心承诺得到解决之前,承诺链继续存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

类似问题但我可以'尽管如此,还是让它继续工作。

Similar question to Promise resolve before inner promise resolved but I can't get it to work nontheless.

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

Every time I think I understand promises, I prove myself wrong!

我有这样写的函数

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

但问题是,即使我返回新的承诺,执行仍然会在任何内心的承诺得到了解决。怎么会?它应该等到异步请求成功并且在 success 回调中调用 resolve()

The problem though is that even if I return new promises, the execution continues down the chain before any of the inner promises are resolved. How come? Shouldn't it wait until the asynchronous request has succeeded and resolve() is called in the success callback?

推荐答案

你这里没有做错任何事。这是jQuery的错, 。

You've done nothing wrong here. This is jQuery's fault, as so often.

问题是jQuery没有兼容(直到v 3.0),并且失败了从其他实现中采用promises / thenable而不是它自己的。因此,当你的回调确实返回RSVP承诺时,jQuery只会将它们视为要实现的值,而不是等待它们。

可以将你的所有承诺强制转换为延迟的jQuery它会工作,但你真的不希望这样。要获得标准的 Promise 行为(由RSVP提供),你需要避免jQuery的错误然后。这个:

The problem is that jQuery is not Promises/A+ compatible (until v 3.0), and fails to adopt promises/thenable from other implementations than its own. So when your callbacks do return RSVP promises, jQuery just treats them as values to fulfill with, instead of waiting for them.
You could cast all of your promises to a jQuery deferred and it would work, but you really don't want that. To get the standard Promise behaviour (as offered by RSVP) to work, you will need to avoid jQuery's buggy then. This 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)
    …

这篇关于在内心承诺得到解决之前,承诺链继续存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-13 01:04