程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了取消vanilla ECMAScript 6 Promise链大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决取消vanilla ECMAScript 6 Promise链?

开发过程中遇到取消vanilla ECMAScript 6 Promise链的问题如何解决?下面主要结合日常开发的经验,给出你关于取消vanilla ECMAScript 6 Promise链的解决方法建议,希望对你解决取消vanilla ECMAScript 6 Promise链有所启发或帮助;

是否有清除.thenJavaScript Promise实例的方法?

不。至少在ECMAScript 6中没有。then默认情况下,不幸的是,承诺(及其处理程序)是无法取消的。关于es- discuss有一些有关如何正确执行此操作的讨论,但是无论哪种方法获胜,都不会在ES6中实现。

当前的观点是,子类化将允许使用您自己的实现来创建可取消的Promise(不确定其效果如何) 。

在语言委托人找到最佳方法之前 (希望是ES7?), 您仍然可以使用userland Promise实现,其中许多功能都取消了。

解决方法

是否有清除.thenJavaScript Promise实例的方法?

我已经在QUnit之上编写了一个JavaScript测试框架。该框架通过在.NET中运行每个测试来同步运行测试Promise。(很抱歉,此代码块的长度。我已尽我所能对其进行了评论,因此它不会那么乏味。)

/* Promise extension -- used for easily making an async step with a
       timeout without the Promise knowing anything about the function 
       it's waiTing on */
$$.extend(Promise,{
    asynctimeout: function (timeToLive,errormessagE) {
        var error = new Error(errormessage || "Operation timed out.");
        var res,// resolve()
            rej,// reject()
            t,// timeout instance
            rst,// reset timeout function
            p,// the promise instance
            at;  // the returned asynctimeout instance

        function createTimeout(reject,temPTTL) {
            return setTimeout(function () {
                // triggers a timeout event on the asynctimeout object so that,// if we want,we can do stuff outside of a .catch() block
                // (may not be needed?)
                $$(at).trigger("timeout");

                reject(error);
            },temPTTL || timeToLivE);
        }

        p = new Promise(function (resolve,reject) {
            if (timeToLive != -1) {
                t = createTimeout(reject);

                // reset function -- allows a one-time timeout different
                //    from the one original specified
                rst = function (temPTTL) {
                    clearTimeout(t);
                    t = createTimeout(reject,temPTTL);
                }
            } else {
                // timeToLive = -1 -- allow this promise to run indefinitely
                // used while debugging
                t = 0;
                rst = function () { return; };
            }

            res = function () {
                clearTimeout(t);
                resolve();
            };

            rej = reject;
        });

        return at = {
            promise: p,resolve: res,reject: rej,reset: rst,timeout: t
        };
    }
});

/* framework module members... */

test: function (name,fn,options) {
    var mod = this; // local reference to framework module since promises
                    // run code under the window object

    var defaultOptions = {
        // default max running time is 5 seconds
        timeout: 5000
    }

    options = $$.extend({},defaultOptions,options);

    // remove timeout when debugging is enabled
    options.timeout = mod.debugging ? -1 : options.timeout;

    // call to QUnit.test()
    test(name,function (assert) {
        // tell QUnit this is an async test so it doesn't run other tests
        // until done() is called
        var done = assert.async();
        return new Promise(function (resolve,reject) {
            console.log("Beginning: " + Name);

            var at = Promise.asynctimeout(options.timeout,"Test timed out.");
            $$(at).one("timeout",function () {
                // assert.fail() is just an extension I made that literally calls
                // assert.ok(false,msg);
                assert.fail("Test timed out");
            });

            // run test function
            var result = fn.call(mod,assert,at.reset);

            // if the test returns a Promise,resolve it before resolving the test promise
            if (result && result.constructor === PromisE) {
                // catch unhandled errors thrown by the test so future tests will run
                result.catch(function (error) {
                    var msg = "Unhandled error occurred."
                    if (error) {
                        msg = error.message + "\n" + error.stack;
                    }

                    assert.fail(msg);
                }).then(function () {
                    // resolve the timeout Promise
                    at.resolve();
                    resolve();
                });
            } else {
                // if test does not return a Promise,simply clear the timeout
                // and resolve our test Promise
                at.resolve();
                resolve();
            }
        }).then(function () {
            // tell QUnit that the test is over so that it can clean up and start the next test
            done();
            console.log("Ending: " + Name);
        });
    });
}

如果测试超时,我的超时Promise将会assert.fail()在测试中进行测试,以便将测试标记为失败,这一切都很好,但是测试继续运行,因为测试Promise(result)仍在等待解决它。

我需要取消试的好方法。我可以通过在框架模块之类的地方创建一个字段this.cancelTest,然后在测试中每隔一段时间(例如在每次then()迭代的开始)检查是否取消来做到这一点。但是,理想情况下,我可以$$(at).on("timeout",/* something here */)用来清除变量中的剩余then()s result,以便不运行其余所有测试。

是否存在这样的东西?

快速更新

我尝试使用Promise.race([result,at.promise])。没用

更新2 +混乱

为了解除对我的限制,我@H_32_3@mod.cancelTest在测试思路中在/ polling上添加了几行。(我还删除了事件触发器。)

return new Promise(function (resolve,reject) {
    console.log("Beginning: " + Name);

    var at = Promise.asynctimeout(options.timeout,"Test timed out.");
    at.promise.catch(function () {
        // end the test if it times out
        mod.cancelTest = true;
        assert.fail("Test timed out");
        resolve();
    });

    // ...

}).then(function () {
    // tell QUnit that the test is over so that it can clean up and start the next test
    done();
    console.log("Ending: " + Name);
});

我在catch语句中设置了一个断点,并且该命中率很高。现在让我感到困惑的是,该then()声明没有被调用。有想法吗?

更新3

想通了最后一件事。 fn.call()抛出了一个我没有捕获的错误,因此测试承诺在at.promise.catch()解决之前就被拒绝了。

大佬总结

以上是大佬教程为你收集整理的取消vanilla ECMAScript 6 Promise链全部内容,希望文章能够帮你解决取消vanilla ECMAScript 6 Promise链所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。