3

Web アプリ、特にファイルのアップロードで作業しているときに、アラートを呼び出した後、Chrome に警告が表示されました。

マイクロタスクの実行中に「alert()」を呼び出すことは非推奨であり、2016 年 9 月頃に M53 で削除される予定です。詳細については、https: //www.chromestatus.com/features/5647113010544640 を参照してください。

ただし、私の状況では呼び出しは正当であり、M53 がリリースされるとコードが機能しないのではないかと少し心配しています。アラートを使用して本番環境に出荷するわけではありませんが、テストには非常に価値があることに注意してください。

状況:

反応を使用して typescript でアプリを開発しています。httpリクエストを行うためにaxiosを使用しています。基本的に、http-post は次のようになります。

axios.post("/upload/", data)
    .then((response: any) => {
        callback(undefined);
    })
    .catch((error: any) => {
        callback(error);
    });

次に、呼び出し元のメソッドで、エラーが発生した場合にアラートをポップして、テスター/開発者に確実に通知されるようにします。このようなちょっと:

this.service.uploadFile((error: any) => {
    if (error) {
        console.log(error);
        alert("An error occured");
        return;
    }

    this.onUploadCompleted()
});

これは、クロムが警告を表示するときです。

まず、リクエストが完了してエラーが返されるまでアラートが表示されるため、警告が正当化されるかどうか疑問に思っています。だから私はそれが何もブロックしていないと確信しています。

正当な理由がある場合、とにかくアラートを表示できるようにするにはどうすればよいですか?

4

1 に答える 1

12

はい、警告は正当化されます。alertマイクロタスク内で呼び出しています。この場合は、promise の完了です。(イベント ループ コンテキスト内のマイクロタスクとマクロタスクの違いを参照してください。)

alertprompt、およびconfirmは過去の時代の遺物であり、問​​題があります。これらは、JavaScript の通常の動作を完全に中断し、ジョブからジョブの途中で実行を完全に中断することによって、実行から完了までのセマンティクスにほぼ間違いなく違反します。キュー (またはイベント ループからのタスク。JavaScript と HTML5 仕様では用語が異なります) を呼び出し、ブロッキング モーダルの形式で UI を実行します。これは、イベントベースの対話の一般的なモード (メッセージを表示し、閉じたときにイベントを取得する) と一致していません。

alert代わりにマクロタスクを実行することで、この問題を回避できます。

this.service.uploadFile((error: any) => {
    if (error) {
        setTimeout(() => {
            console.log(error);
            alert("An error occured");
        }, 0);
        return;
    }

    this.onUploadCompleted()
});

...しかし、実際の解決策は、、、およびの使用をalert完全にやめることです。promptconfirm


マイクロ タスクとマクロ タスクの楽しい例を次に示します。promise の完了はmicrotask ですが、タイマー コールバックはmacrotaskです。DOM イベント コールバックと同様に、スクリプトの最初の実行もマクロタスクです。マクロタスクによってキューに入れられたすべてのマイクロタスクは、次のマクロタスクが実行される前に実行されます。たとえば、キュ​​ーをジャンプします。だからこれで:

// First, we set a timer callback for 0ms
setTimeout(() => {
  console.log("timer fired");
}, 0);

// Now we get a promise that's *already* resolved and hook a callback
Promise.resolve().then(() => {
  console.log("promise resolved");
});

// Now show a message demonstrating we got here before the promise resolution callback
console.log("got to the end");

...私たちは見る

最後になりました
約束は解決した
タイマー発射

...それよりも

最後になりました
タイマー発射
約束は解決した

....すべてのタスクが同じように作成されていれば、これは得られたでしょう。

于 2016-08-25T07:55:10.760 に答える