2015-12-18 131 views
14

我目前正在試驗承諾並有一個非常基本的問題!ES6承諾 - 在承諾鏈中調用同步功能

在承諾鏈中,調用同步函數是不好的做法嗎?例如:

.then(function(results) { 

    if(checkIfResultInMemory(results) === true){ 
     return getTotalFromMemory() 
    } 

    return results; 

    }) 

還是應該我同步功能進行重構,也返回的承諾?

+0

可能的複製[當製作函數異步使用Promises](http://stackoverflow.com/q/28993673/1048572) – Bergi

+0

永遠不要使用同步函數的承諾。 – Bergi

回答

26

在承諾鏈中,調用同步 函數是不好的做法嗎?

不,這根本不是壞習慣。這是許多預期和有用的做法之一。

您可以完全自由地調用承諾鏈中的同步函數(從.then()處理程序中)或異步函數,然後返回新的承諾。

當您從.then()處理程序返回某些東西時,您可以返回一個值(它成爲父承諾的解析值),或者可以返回另一個承諾(鏈接到前一個承諾),或者可以拋出像返回被拒絕的承諾(承諾鏈被拒絕)。

所以,這意味着您可以調用同步函數並從中獲取值或調用異步函數並獲取另一個承諾,然後從.then()處理函數中返回。

所有這些同步事物都是完全合法的,每個都有自己的目標。下面是在.then()處理一些同步發生的事情:

// modify resolved value 
someAsync().then(function(val) { 
    return val + 12; 
}); 

// modify resolved value by calling some synchronous function to process it 
someAsync().then(function(val) { 
    return someSynchronousFunction(val); 
}); 

// synchronously check the value and throw to change the promise chain 
// to rejected 
someAsync().then(function(val) { 
    if (val < 0) { 
     throw new Error("value can't be less than zero"); 
    } 
    return val; 
}); 

// synchronously check the value and return a rejected promise 
// to change the promise chain to rejected 
someAsync().then(function(val) { 
    if (val < 0) { 
     return Promise.reject("value can't be less than zero"); 
    } 
    return val; 
}); 

下面是返回一個承諾,然後3個同步.then()處理,然後輸出最終值的異步操作的一個小例子:

function delay(t, val) { 
 
    return new Promise(function(resolve) { 
 
     setTimeout(function() { 
 
      resolve(val); 
 
     }, t); 
 
    }); 
 
} 
 

 
function increment5(val) { 
 
    return val + 5; 
 
} 
 

 
delay(500, 10).then(increment5).then(function(val) { 
 
    return val - 3; 
 
}).then(function(final) { 
 
    document.write(final); 
 
});

注意:你一般只想要當你有或可能有異步操作時使用promise,因爲如果所有內容都是同步的,那麼純同步代碼的執行速度更快,而且寫起來更容易。但是,如果您已經有至少一個異步操作,那麼您當然可以將同步操作與該異步操作混合在一起,並使用promise來幫助構建代碼。

+0

非常感謝@ jfriend00 - 的確非常有幫助!謝謝你的時間。 – Ben

+1

爲什麼downvote?一個普遍接受的答案Downvotes沒有任何相應的評論,解釋了爲什麼你認爲它值得downvote沒有真正貢獻很多的社區。如果你解釋,那麼作者可以改進他們的答案來解決你的問題,並改善所有人的答案。 Driveby downvoting無助於改善其他社區的情況。 – jfriend00

+0

優秀的答案。比神話「永遠不會做同步承諾」要好得多。謝謝。 – Kim

2

一個then回調函數應:

  • 返回另一個承諾
  • 返回同步值(或未定義)
  • 拋出一個同步錯誤的
+0

「承諾之內」,我假設你的意思是「在一個'然後'處理程序」? –

+0

是的,讓我解決這個問題:D – trquoccuong

+0

我不明白你的意思。編碼具體部分。 – Internial