Я перебираю массив js
с eachOf
из asny c framework и выполняю асинхронную функцию в каждой итерации. Если вызывается callback
и не было выдано никакой ошибки, код достиг оператора возврата. Мне интересно, почему возвращение игнорируется и не сразу покидает цепочку обещаний. Если я оберну еще одно обещание вокруг функции eachOf
и разрешу значение в функции обратного вызова, обещание первого уровня будет выполнено, как и ожидалось.
Почему это так? Разве возврата в функции обратного вызова не достаточно для завершения функции?
app1. js
const module1 = require('./module1');
const errorHandler = require('./error'); //implements custom error handler, e.g. log, mail, prowl, etc.
module1.getSomeVals()
.then(result => {
console.log('this is result:', result); //this returns undefined because the return in module1 not working
})
.catch(e => {
errorHandler.handle(e);
});
module1. js
const async = require('async'); //node module
const db = require('./db'); //custom db class
const module1 = {};
module1.getSomeVals= () => {
return new Promise(resolve => {
//some asyncronous function resolves values for next chain element, e.g. database stream
const resultFromSomeAsyncFunction = [
{
foo: 'foo1',
bar: 'bar1'
},
{
foo: 'foo2',
bar: 'bar2'
},
{
foo: 'foo3',
bar: 'bar3'
},
];
resolve(resultFromSomeAsyncFunction);
})
.then(results => {
let newResults = [];
async.eachOf(results, (result, index, callback) => {
return db.query("select * from names where foo = '" + result.foo + "' and bar = '" + result.foo)
.then(rows => {
newResults.push(rows);
console.log('this is rows:', rows);
callback(null); //doesn't need second parameter, because newResults defined above
})
.catch(e => {
callback(e); //throw e works as well
});
},
(err) => {
if (err)
throw err;
else {
console.log('this is newResults:', newResults); //this is the new result as expected.
return newResults; //this return doesn't exit the function as expected and the next log will be reached
}
});
console.log('this is newResults and shouldn\'t reached at all:', newResults); //this line will be reached, but should'nt
});
};
module.exports = module1;
app2. js
const module2 = require('./module2');
const errorHandler = require('./error'); //implements custom error handler, e.g. log, mail, prowl, etc.
module2.getSomeVals()
.then(result => {
console.log('this is result:', result); //this returns the expected newResults array because the wrapped promise resolves the newResults
})
.catch(e => {
errorHandler.handle(e);
});
module2. js
const async = require('async'); //node module
const db = require('./db'); //custom db class
const module2 = {};
module2.getSomeVals = () => {
return new Promise(resolve => {
//some asyncronous function resolves values for next chain element, e.g. database stream
const resultFromSomeAsyncFunction = [
{
foo: 'foo1',
bar: 'bar1'
},
{
foo: 'foo2',
bar: 'bar2'
},
{
foo: 'foo3',
bar: 'bar3'
},
];
resolve(resultFromSomeAsyncFunction);
})
.then(results => {
let newResults = [];
return new Promise(resolve => {
async.eachOf(results, (result, index, callback) => {
return db.query("select * from names where foo = '" + result.foo + "' and bar = '" + result.foo)
.then(rows => {
newResults.push(rows);
console.log('this is rows:', rows);
callback(null); //doesn't need second parameter, because newResults defined above
})
.catch(e => {
callback(e); //throw e works as well
});
},
(err) => {
if (err)
throw err;
else {
console.log('this is newResults:', newResults); //this is the new result as expected.
resolve(newResults); //this resolve exit the function as expected and the next log wont be reached
}
});
});
console.log('this is newResults and shouldn\'t reached at all:', newResults); //this line wont be reached as expected
});
};
module.exports = module2;
Module2 имеет стиль кода, похожий на беспорядок. Я хочу иметь чистую и стабильную структуру в коде.
Документы asyn c eachOf говорят:
Обратный вызов, который вызывается, когда все функции iteratee завершены или возникает ошибка. Вызывается с (err).
Возвращает: обещание, если обратный вызов пропущен
Тип Обещание
Учитывая, что обратного вызова, такого как resolve
, больше нет, я за исключением того, что возврат должен закончиться обещанием. Я хочу понять, почему поведение ведет себя так.