非同期カプセル化の改善: 戻り値による非同期呼び出しの処理 - Border City Inn

hzc
リリース: 2020-06-23 10:07:23
転載
2957 人が閲覧しました
最後のいくつかの記事は WeChat ミニ プログラムの開発に関連しているため、誰かが「ミニ プログラムが理解できません。何か別のことを書いてもらえますか?」と尋ねました。

実際には、「小さなプログラム」ということにあまり注意を払う必要はありません。「小さなプログラム」はこの記事の開発シナリオにすぎないからです。私たちが実際に解決する問題は、小さなプログラムでのみ発生するわけではありません。 、そして問題を解決する手段は完全に ミニプログラムとは関係ありません!

1. 問題

プロキシによってカプセル化された WeChat アプレットの非同期呼び出しには問題が残っています:

Like wx.request() 戻り値があるこの状況をカプセル化するにはどうすればよいでしょうか?

リクエストの処理中にリクエストをキャンセルする必要がある場合は、wx.request() の戻り値:

const requestTask = wx.request(...);
if (...) {
    // 因为某些原因需要取消这次请求
    requestTask.abort();
}
ログイン後にコピー

Encapsulated awx が使用されます。 request() は Promise オブジェクトを返しますが、これは wx.request() の元の戻り値とは何の関係もありません。リクエストをキャンセルできるようにしたい場合は、wx.request() の元の戻り値を取り出す必要があります。

function wxPromisify(fn) {
    return async function (args) {
        return new Promise((resolve, reject) => {
            const originalResult = fn({
//          ^^^^^^^^^^^^^^^^^^^^^^^
//          怎么把 originalResult 带出去?
                ...(args || {}),
                success: res => resolve(res),
                fail: err => reject(err)
            });
        });
    };
}
ログイン後にコピー

2. 代替オプション

それほど複雑ではありませんが、いくつかのオプションを示します:

  1. オブジェクトまたは配列を返し、後で使用します。脱構築。たとえば、return {promise,originalResult} または [promise,originalResult];
  2. は、## などの「コンテナ」パラメータを通じて戻り値を取り出します。 #awx.request(params, outBox = {})、処理中に outBox に値を割り当てます: outBox.originalResult;
  3. JS は動的型です追加の属性:
  4. promise.originalResult = ... を使用して、Promise オブジェクトを直接変更できます。
ユーザーの観点から見ると、ほとんどの場合、元の戻り値は必要ありません。現時点では、それを分解するのではなく、必ず

await awx.request() を使用したいと考えています。 then await (または then()) なので、最初のメソッドはオプションではありません。

2 番目の方法は実行可能であり、元の戻り値が必要ない場合に直接使用できます。ただし、独自の戻り値が必要な場合は、コンテナオブジェクトを生成して渡す必要があるので、少し面倒です。

3 番目の方法は、最も「無害」に使用できるはずです。いずれにせよ、Promise オブジェクトによって本来の価値が引き出されるので、使うかどうかは関係なく、自由に使ってください。

次に 3 番目のメソッドを実装して

wxPromisify() を変換しましょう:

3. 失敗しました

1 私はそう思いました最初は非常に単純でした。最初は

return new Promise() だけでしたが、今は一時変数を追加するだけです:

function wxPromisify(fn) {
    return async function (args) {
        const promise = new Promise((resolve, reject) => {
//      ^^^^^^^^^^^^^^^^
            promise.originalResult = fn({
//          ^^^^^^^^^^^^^^^^^^^^^^^^^
                ...(args || {}),
                success: res => resolve(res),
                fail: err => reject(err)
            });
        });
        
        return promise;
//      ^^^^^^^^^^^^^^^
    };
}
ログイン後にコピー
その後、エラーが発生しました:

TypeError: Cannot set property 'originalResult' of undefined
ログイン後にコピー
この間違いは理解しやすく、修正するのも簡単です...しかし、犯しやすいものでもあります。

当初、

promise はローカル変数であり、直接アクセスできるため、サブスコープで使用しても問題ないと考えていました。ただし、このサブスコープがコンストラクター内にあることはここでは無視されます。大まかな分析をしてみましょう:

new Promise() はパラメータとして関数 (factory と呼ばれるものとします) を必要としますが、この関数の実行のタイミングは factory それは何ですか? new Promise() が Promise インスタンスを生成した後は、このインスタンスのメソッドを積極的に呼び出していないことに注意してください。したがって、構築プロセス中に factory が実行されると結論付けることができます。つまり、この時点では Promise インスタンスはまだ生成されておらず、promiseundefine を参照します。

4. 成功した試み

問題がわかったので、分析を続けましょう。

factory は Promise インスタンスの構築中に呼び出され、factory は関数本体で直接実行され、すぐに取得できます fnの戻り値なので、Promise インスタンスが構築された後は、元の戻り値を取得できます。 ここでコードを変更しましょう:

function wxPromisify(fn) {
    return async function (args) {
        let originalResult;
//      ^^^^^^^^^^^^^^^^^^^
        const promise = new Promise((resolve, reject) => {
            originalResult = fn({
//          ^^^^^^^^^^^^^^
                ...(args || {}),
                success: res => resolve(res),
                fail: err => reject(err)
            });
        });

        promise.originalResult = originalResult;
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        return promise;
    };
}
ログイン後にコピー

new Promise()

の後の

promise.originalResult に値を割り当てる必要があります。この " value" new Promise() の処理で生成されるので、ローカル変数 originalResult を追加するだけで取り出せます。 ###### 終わり! 5. 面白いけど真剣に受け止めるべきこと

終わったはずだけど誰かがやるだろう(他のシーンで見たことあるから) ):

注: 以下はエラーの例です。
function wxPromisify(fn) {
    return async function (args) {
        let promise = new Promise();
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        promise = new Promise((resolve, reject) => {
//      ^^^^^^^^^^
            promise.originalResult = fn({ ... });
//          ^^^^^^^^^^^^^^^^^^^^^^
        });

        return promise;
    };
}
ログイン後にコピー

これを実行すると、上記の

TypeError

は生成されませんが、外部から取得した Promise オブジェクトには
originalResult
が含まれません。具体的な理由は上記の失敗した場合と同じなので、詳細は説明しませんが、覚えておいてください:

ここでは 2 つの Promise オブジェクトが生成されます

6. 再び

今回は例としてwx.request()を使用して元の戻り値を取り出します。その戻り値の主な目的は次のとおりです。リクエストをキャンセルするための .abort() メソッドを提供します。このアプリケーション シナリオは、実際には Axios が「キャンセル」を処理する方法と似ているため、cancelToken を通じて Axios によって実装されたメソッドを参照することもできます。 cancelToken の本質は、上で説明した 2 番目のメソッド、つまり、必要なものを取り出すために「コンテナ」オブジェクトを渡すことです。 Promise オブジェクトを通じてそれを取り出すことは、特別な「コンテナ」オブジェクトを通じてそれを取り出すことと本質的に同じであるため、これ以上は説明しません。

推奨チュートリアル: 「WeChat ミニ プログラム

以上が非同期カプセル化の改善: 戻り値による非同期呼び出しの処理 - Border City Innの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート