等待非即時的事物
有 時積木必須在指令碼繼續之前等待非同步操作。網路請求是經典示例:無論您的連線多快,請求都不可能是即時的。
積木表示"我還沒完成"的方式是返回一個 Promise。Bilup 在執行下一個積木之前等待 Promise 解析,並且可能同時執行其他指令碼(下載):
class AsyncExtension {
getInfo() {
return {
id: 'asyncexample',
name: 'Async Blocks',
blocks: [
{
opcode: 'wait',
text: 'wait [TIME] seconds',
blockType: Scratch.BlockType.COMMAND,
arguments: {
TIME: { type: Scratch.ArgumentType.NUMBER, defaultValue: 1 }
}
},
{
opcode: 'fetch',
text: 'fetch [URL]',
blockType: Scratch.BlockType.REPORTER,
arguments: {
URL: {
type: Scratch.ArgumentType.STRING,
defaultValue: 'https://extensions.bilup.org/hello.txt'
}
}
}
]
};
}
wait(args) {
return new Promise((resolve) => {
setTimeout(resolve, args.TIME * 1000);
});
}
fetch(args) {
return fetch(args.URL)
.then((response) => response.text())
.catch((error) => {
console.error(error);
return 'Uh oh! Something went wrong.';
});
}
}
Scratch.extensions.register(new AsyncExtension());
非同步積木在 getInfo() 中宣告的方式與其他積木完全一樣。唯一改變的是函式返回什麼。
關於兩個積木的說明
wait 積木大致是 Scratch 內建的 wait 積木。setTimeout 不使用 Promise,因此我們手動構造一個並在超時內解析它。因為 wait 是命令(無返回值),它解析時不帶任何值。
fetch 積木請求一個 URL,就像畫廊中的"Fetch"擴充功能一樣。fetch() 已經返回一個 Promise,因此我們在它上面連結,而不是製作新的。報告積木必須返回字串、數字或布林值的規則仍然適用,因此我們呼叫 .text() 將 Response 物件變成字串。