2015-09-09 187 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,我從來沒有想過可能是因爲這個原因,但現在它確實有效!非常感謝! –