NodeJS возвращает данные из вложенного обещания

#javascript #node.js #es6-promise

#javascript #node.js #es6-обещание

Вопрос:

Я довольно новичок в promises и мог бы поделиться любыми указателями на то, как заставить это работать. Ни одному из вариантов, которые я пробовал, не удалось запустить окончательные обратные вызовы с успехом / ошибкой или удалось, но не вернули данные.

 export function getData(start, end, tagSet){
    let data = new dataSet();
    // Initial setup to work out what data to fetch

    return database.Read(config).then(function (results) {
        // Process the results.......
        return data;
    }, function (errCode) {
        // Throw Error
    });
}

// Call the function, triggered by a seperate event
getData.then(function(data){
    //Success !!
    
},function(err){
    //Failure!!
    
});
 

Я также попытался настроить новое обещание

 export function getData(start, end, tagSet){
    let data = new dataSet();
    // Initial setup to work out what data to fetch

    return new Promise(function(resolve, reject) {
        database.Read(config).then(function (results) {
            // Process the results.......
            // Update data
        }, function (errCode) {
            // Throw Error
        });
        return data;
    }
}
 

Я не хочу блокировать функцию getData с помощью await, так каков правильный способ возврата данных из обещания внутри функции?

  • Редактировать: опечатка
  • Похоже, я неправильно понял, как await работает внутри асинхронной инструкции.

Комментарии:

1. getData.then(...) вам нужно вызвать getData getData(start, end, tagSet).then(...)

2. Извиняюсь, это была опечатка в вопросе — в фактическом коде это было — я просто случайно пропустил его, упрощая его для вопроса.

3. Тогда ошибка должна быть где-то в коде, который вы удалили, чтобы упростить код, потому что ваш первый фрагмент должен в принципе работать.

Ответ №1:

Вы ничего не возвращаете из обещаний, а вместо этого разрешаете или отклоняете обещание.

ваш 2-й пример должен выглядеть примерно так

     export function getData(start, end, tagSet){
    let data = new dataSet();
    // Initial setup to work out what data to fetch

    return new Promise(function(resolve, reject) {
        database.Read(config).then(function (results) {
            // Process the results.......
            // Update data
        }, function (errCode) {
            // Throw Error
            reject(errCode) // <-- if error happens, you reject your promise with error
        });
        resolve(data) // <<-- if there is no error, you resolve your data
    }
 }
 

затем вы можете использовать

 getData.then(function(data){
   //promise is resolved
})
.catch(function(err){
   //promise was rejected
})
 

Комментарии:

1. Спасибо за вашу помощь — решение похоже на то, что я искал, однако я дал код, который вы предложили попробовать, и обещание getData разрешается до запуска database.Read().then() .

2. Нет. Первый, в вашем примере, resolve(data) вызывается до database.Read(config) завершения. Он не будет ждать results обработки и не будет ждать, чтобы узнать, произошла ли ошибка. Это будет всегда и немедленно resolve(data) . Во-вторых, весь подход является антишаблоном. Нет необходимости создавать new Promise , потому database.Read(config) что уже возвращает обещание.

Ответ №2:

Похоже, решение, которое я хотел, состояло в том, чтобы установить функцию как асинхронную и использовать ожидание.

 export async function getData(start, end, tagSet){
    let data = new dataSet();
    // Initial setup to work out what data to fetch

    await database.Read(config).then(function (results) {
        // Process the results.......
        // update data
    }, function (errCode) {
        // Throw Error
    });
    
    return data;
}

// Call the function, triggered by a seperate event
getData().then(function(data){
    // Success !!
    // data has been completed here
},function(err){
    // Failure!!
    
});
 

Это приводит к тому, что возвращаемые данные завершаются до того, как запускается getData().then() .