异步链接模式

时间:2019-10-11 19:46:16

标签: javascript node.js

考虑以下情况:

var Calc = function () {
   // proprties
   this.value = 0

   // handler's
   this.Add = (__value) => { this.value = this.value + __value; return this }
   this.Subtract = (__value) => { this.value = this.value - __value; return this }
}

var = (new Calc()).Add(2).Subtract(1) // console.log() => 1

但是如果您将Object封装在异步中,则等待类似

var Calc = async function () {
   // proprties
   this.value = 0

   // handler's
   this.Add = async (__value) => { this.value = this.value + __value; return this }
   this.Subtract = async (__value) => { this.value = this.value - __value; return this }
}

(await new Calc()).Add(2).Subtract(1) // console.log() => undefined
(await (await new Calc()).Add(2)).Subtract(1) // console.log() => 1

我知道Promise返回的原因需要解决,因为您只需将代码包装在()中,一旦执行了语句,您就可以继续链接。

我在寻找什么。

await newCalc().Add(2).Subtract(1) // console.log() => 1

1 个答案:

答案 0 :(得分:2)

需要注意的是,await只能在async函数中使用,可以使用所需的API,只是稍微复杂一点。

大量的库,例如knexjQuerynightmare.js实现链接以组成异步操作。但是可链接的方法不是异步的。相反,异步操作仅在操作结束时(需要结果时)执行,但方法本身是同步的。例如,对于knex,仅在调用.then()时执行异步操作。

这是一种实现方法:

function Calc () {
    this.operations = [];
    this.value = 0;
}

Calc.prototype = {
    add: function (x) {
        // schedule a function that performs async addition:
        this.operations.push(() => {
            return new Promise(ok => {
                ok(this.value + x);
            });
        });
        return this;
    },
    subtract: function (x) {
        // schedule a function that performs async subtraction:
        this.operations.push(() => {
            return new Promise(ok => {
                ok(this.value - x);
            });
        });
        return this;
    },
    // THIS IS WHERE WE DO OUR MAGIC
    then: async function (callback) {
        // This is finally where we can execute all our
        // scheduled async operations:
        this.value = 0;
        for (let i=0; i<this.operations.length; i++) {
            this.value = await operations[i]();
        }
        return callback(this.value); // since the await keyword will call our
                                     // then method it is the responsibility of
                                     // this method to return the value.
    }
}

现在您可以像这样使用它:

async function main () {
    let x = await new Calc().add(2).subtract(1);
    console.log(x);
}
main();

请注意,上面的代码在功能上等同于:

new Calc().add(2).subtract(1).then(x => console.log(x));