Каковы преимущества использования выхода в качестве асинхронного потока управления? - PullRequest
1 голос
/ 05 июня 2019

Angular's Служебный работник использует 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());
    });
};

Что очень похоже на _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 для асинхронного потока управления?Я не видел абсолютно никакой разницы между yield и await с точки зрения поддержки браузера на caniuse.com .

Другими словами

Какой смысл использовать это:

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 Ответ

1 голос
/ 05 июня 2019

Разница заключается в том, что Promises предназначены для выполнения одноразовых задач, когда генераторы предназначены для повторения задачи до тех пор, пока список задач не будет исчерпан. Если список никогда не исчерпывается, то генератор продолжит работу, как если бы это был не основанный на времени (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, когда это необходимо.

...