Обратный звонок внутри Promise.all - PullRequest
0 голосов
/ 22 января 2020

У меня есть сомнения в использовании Promise.all. Мне нужно иметь три функции с обратными вызовами. Поэтому я пишу эти три функции в Promise.all, а затем получаю результат всех трех функций в .then () Promise.all. Это правильный путь или есть другой способ?

Ответы [ 2 ]

3 голосов
/ 22 января 2020

Звучит так, будто вы все делаете правильно, да; было бы лучше, если бы вы показали код.

Но допустим, вы хотите запустить три процесса, которые запускаются doThis(), doThat() и doTheOther(). Вы обрабатываете это так:

Promise.all([
    doThis(),
    doThat(),
    doTheOther()
])
.then(([thisResult, thatResult, theOtherResult]) => { // The destructuring is optional, of course
    // ...use them...
})
.catch(error => {
    // ...handle/report error...
});

Ключевые биты:

  1. Вы передаете итерируемое значение Promise.all (я использовал массив выше)
  2. Вы получаете результаты в том же порядке, что и итерируемые (независимо от того, в каком порядке все выполнено)
  3. Promise.all обещание отклоняется, если любая операций отклоняет.

В комментарии вы разместили этот код:

Promise.all([
    client.query(q1,function(err,res){ dosomething();}),
    client.query(q2,function(err,res){ dosomething();})
])
.then(() => {
    dosomething()};
})  // <== Added missing }
.catch(e => {
    console.log(e); // <== Added missing ;
}); // <== Added missing ;

Это выглядит неправильно. Обычно, когда функция принимает обратный вызов, как вы делаете query, она не возвращает обещание. Проверьте документацию на query звонок, который вы делаете.

Если вернет обещание, вы будете использовать его следующим образом:

Promise.all([
    client.query(q1).then(dosomething),
    client.query(q2).then(dosomething)
])
.then(() => {
    dosomething()};
})  // <== Added missing }
.catch(e => {
    console.log(e); // <== Added missing ;
}); // <== Added missing ;

... при условии, что вы хотите, чтобы doSomething вызывался только при успешном выполнении запроса (ваш код вызывал его независимо от того, был ли запрос успешным или нет).

Если query не возвращает обещание, вы ' оберните это во что-то, что делает, как это:

function doQuery(client, q) {
    return new Promise((resolve, reject) => {
        client.query(q, function(err, res) {
            if (err) {
                reject(err);
            } else {
                resolve(res);
            }
        });
    });
}

, затем используйте это:

Promise.all([
    doQuery(client, q1).then(doSomething),
    doQuery(client, q2).then(doSomething)
])
.then(() => {
    dosomething()};
})  // <== Added missing }
.catch(e => {
    console.log(e); // <== Added missing ;
}); // <== Added missing ;

(Опять же, я предположил, что doSomething следует вызывать только тогда, когда запрос был успешным.)

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

const doQuery = util.promisify(client.query.bind(client)); // Note the .bind(client)
Promise.all([
    doQuery(q1).then(doSomething),
    doQuery(q2).then(doSomething)
])
.then(() => {
    dosomething()};
})  // <== Added missing }
.catch(e => {
    console.log(e); // <== Added missing ;
}); // <== Added missing ;
0 голосов
/ 22 января 2020

Вам нужно обернуть обратные вызовы в обещание разрешить их все с помощью Promise.all

Итак:

Promise.all([
    new Promise(resolve => client.query(q1, function(err, result) { resolve(result); }) ),
    new Promise(resolve => client.query(q2, function(err, result) { resolve(result); }) ),
    new Promise(resolve => client.query(q3, function(err, result) { resolve(result); }) )
]).then(([q1, q2, q3]) => {
   //do something with results
}).

Если вам нужно обработать ошибки, вам придется отклонить ошибка.

Надеюсь, что поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...