ex14-03-8
ソース
function countdown(seconds) {
return new Promise(function(onFulfilled, onRejected) {
const timeoutIds = [];
for(let i=seconds; i>=0; i--) {
timeoutIds.push(setTimeout(function() {
if(i===13) {
timeoutIds.forEach(clearTimeout); /* すべてクリア */
return onRejected(new Error(`${i}という数は不吉過ぎます`));
}
if(i>0) console.log(i + '...');
else onFulfilled(console.log("GO!"));
}, (seconds-i)*1000))
}
});
}
function launch() {
return new Promise(function(onFulfilled, onRejected) {
if(Math.random() < 0.5) /* 打ち上げ失敗 */
// return onRejected(new Error("打ち上げ失敗!"));
return;
console.log("発射!");
setTimeout(function() {
onFulfilled("周回軌道に乗った!");
}, 2*1000); /* 超速のロケット */
});
}
// #@@range_begin(list1)
function addTimeout(fn, /* タイムアウトをアタッチする関数 */
period /* タイムアウトの時間 */
) {
if(period === undefined) period = 1000; /* デフォルトの設定 */
return function(...args) {
return new Promise(function(onFulfilled, onRejected) {
const timeoutId = setTimeout(onRejected, period,
new Error("プロミス タイムアウト"));
fn(...args)
.then(function(...args) {
clearTimeout(timeoutId);
onFulfilled(...args);
})
.catch(function(...args) {
clearTimeout(timeoutId);
onRejected(...args);
});
});
}
}
// #@@range_end(list1)
// #@@range_begin(list2)
countdown(3)
.then(addTimeout(launch, 4*1000)) /* タイムアウトを4秒に設定 */
.then(function(msg) {
console.log(msg);
})
.catch(function(err) {
console.error("管制塔、管制塔。トラブル発生... " + err.message);
});
/* 実行結果1
3...
2...
1...
GO!
発射!
周回軌道に乗った!
*/
/* 実行結果2
3...
2...
1...
GO!
管制塔、管制塔。トラブル発生... プロミス タイムアウト
*/
// #@@range_end(list2)