Можно ли разрешить асинхронную функцию без ключевого слова return

Я начал использовать функцию ES7 async/await, которая дает лучший подход к решению асинхронных задач и делает ваш код более чистым и читаемым.

Однако он не дает вам доступа к обещанию, созданному функцией async, поэтому, если вы выполняете какой-либо асинхронный запрос в своей функции async, вы должны обещать его, затем дождаться его и затем вернуть результат. Я имею в виду это:

async function doStuff() {
    //stuff...
    var value = await new Promise(function(resolve) {
        $.get('http://some/url/...', function(result) {
            // stuff...
            resolve(result);
        });
    });
    return value;
}

Что, если бы вы могли найти указатель на обещание, созданное функцией, чтобы ваш код выглядел так:

async function doStuff() {
    //stuff...
    var p = arguments.callee.promise;
    $.get('http://some/url/...', function(result) {
        // stuff...
        p.resolve(result);
    });
}

или даже:

async function doStuff() {
    //stuff...
    $.get('http://some/url/...', function(result) {
        // stuff...
        async.resolve(result);
    });
}

Таким образом, вам не нужно напрямую обращаться к Promises API, что делает ваш код полностью сфокусированным на задаче без чего-либо другого.


person rokstar    schedule 09.11.2016    source источник
comment
Я думаю, вы упускаете суть _1 _ / _ 2_. Можете ли вы создать сценарий, в котором простого выполнения result = await $.get(someUrl); doStuffWith(result) недостаточно? Весь смысл предложения не в том, чтобы иметь дело с обратными вызовами.   -  person Amadan    schedule 09.11.2016
comment
Я просто подумал, если ты уже обещал, зачем тебе создавать еще один. Берги внизу ответил четко - Нет. =)   -  person rokstar    schedule 09.11.2016
comment
Учтите это, если вы случайно зашли сюда за своим необычным кодом: stackoverflow.com/questions/26150232/.   -  person Константин Ван    schedule 01.01.2020


Ответы (3)


Можно ли разрешить асинхронную функцию без ключевого слова return

No.

Невозможно получить ссылку на обещание, созданное вызовом async function, но на самом деле нет необходимости получать доступ к нему (и, кстати, вы не можете .resolve() обещание, вам действительно нужно получить доступ к обещанию разрешающие функции).

Весь смысл _3 _ / _ 4_ в том, чтобы хорошо поиграть с обещаниями и другими объектами. Идея состоит в том, что каждая асинхронная функция возвращает обещание, и вам не нужно ничего обещать (но если вам действительно нужно, сделайте это отдельно) - и фактически $.get делает вернуть обещание (jQuery). Так что просто напишите

async function doStuff() {
    //stuff...
    var result = await $.get('http://some/url/...');
    // stuff...
    return someValue;
}

Если у вас действительно есть функция обратного вызова, используйте простой

async function doStuff() {
    // stuff…
    return new Promise(function(resolve, reject) {
        $.get({
            url: 'http://some/url/...',
            success: resolve,
            error: reject
            // don't do other "stuff" in here
        });
    });
}
person Bergi    schedule 09.11.2016

Когда вы возвращаете обещание из функции, функция не должна быть асинхронной, на самом деле это даже плохо, потому что вы создаете два обещания!

function doStuff() {
    return new Promise(function(resolve, reject) {
        $.get('http://some/url/...', result => resolve(result));
    });
}

async function main() {
    const result = await doStuff();
}
person Ali    schedule 28.07.2017

Как насчет создания ваших асинхронных функций, а затем использования await при их вызове.

  //define
  async promiseFunction(foo) {
    return otherPromiseFunction(foo);
  async promiseFunction2(foo) {
    return '10';
  }
  async promiseFunction3(foo) {
    return new Promise((resolve, reject) => {
      resolve('foo')
    })
  }
//invoke
  anotherPromiseFunction(bar).then(async foo => {
    const fooResult = await promiseFunction(foo);
    return fooResult; 
  })
person ariel guzman    schedule 16.08.2018