2015-09-09 215 views
1

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

的问题是,虽然即使我回复了新的承诺,在内部承诺解决之前,执行继续下去。怎么来的?难道它不应该等到异步请求成功并且在success回调中调用resolve()

+0

请问您能提供一个更小且完整的代码片段来重现此问题吗?从这里我没有看到你的代码有任何缺陷,应该工作。 –

+0

这一定是事实,并非所有的异步函数都会返回一个承诺。我会尝试修改代码以实现它! –

+1

不要忘记在错误回调中拒绝。你真的应该替换那个'alert'例如 – Bergi

回答

3

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

问题是,jQuery不是Promises/A+兼容(直到v 3.0),并且未能采用自己以外的其他实现的promise/thenable。所以,当你的回调函数返回RSVP promise时,jQuery将它们当作值来实现,而不是等待它们。
可能把你所有的承诺都投给了jQuery延期,它会工作,但你真的不想这样做。要获得标准的Promise行为(如RSVP提供的),您需要避免jQuery的bug 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) 
    … 
+0

1):这也发生[这里](http://stackoverflow.com/a/31976947/1048572)与本机承诺和[这里](http://stackoverflow.com/a/31462113/1048572)与RSVP – Bergi

+0

Geebus,我从来没有想过可能是因为这个原因,但现在它确实有效!非常感谢! –