使用yield作为异步控制流有什么好处?

时间:2019-06-05 16:09:47

标签: javascript async-await yield control-flow

Angular的promise使用yield进行异步控制。然后将每个生成器函数传递给该函数:

var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

与Babel的_asyncToGenerator

非常相似
function _asyncToGenerator(fn) {
    return function () {
        var gen = fn.apply(this, arguments);
        return new Promise(function (resolve, reject) {
            function step(key, arg) {
                try {
                    var info = gen[key](arg);
                    var value = info.value;
                } catch (error) {
                    reject(error);
                    return;
                }
                if (info.done) {
                    resolve(value);
                } else {
                    return Promise.resolve(value).then(function (value) {
                        return step("next", value);
                    }, function (err) {
                        return step("throw", err);
                    });
                }
            }

            return step("next");
        });
    };
}

yield用于异步控制流有什么好处?就Service worker上的浏览器支持而言,我发现yieldawait之间绝对没有区别。

换句话说

使用这个有什么意义?

var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

__awaiter(this, void 0, void 0, function* () {
    const foo = yield 3;
    const bar = yield new Promise(resolve => resolve(7));
    const baz = bar * foo;
    console.log(baz);
});

代替此:

(async function () {
    const foo = await 3;
    const bar = await new Promise(resolve => resolve('7'));
    const baz = bar * foo;
    console.log(baz);
})();

为此:

1 个答案:

答案 0 :(得分:1)

区别在于,Promise旨在执行一次完成任务,在这种情况下,生成器被设计为重复执行任务,直到任务列表用尽。如果列表从不耗尽,则生成器将继续运行,就像它是可以在操作之间暂停的非基于时间(setInterval())的迭代器一样。

这在生成器的MDN示例中可以看到:

function* idMaker() {
  var index = 0;
  while (true)
    yield index++;
}

var gen = idMaker(); // "Generator { }"

console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2

while循环产生了Promise对象,它类似于您提供的源样本。然后,生成器将通过根据需要重复生成Promise对象来生成用于异步操作的控制流

您在样本中提供的逻辑通过在需要时履行Promise合同,将情况进一步推了一些。