async在await循环中使用是否有任何问题?我正在尝试循环遍历文件数组和forEach每个文件的内容.
import fs from 'fs-promise'
async function printFiles () {
const files = await getFilePaths() // Assume this works fine
files.forEach(async (file) => {
const contents = await fs.readFile(file, 'utf8')
console.log(contents)
})
}
printFiles()
Run Code Online (Sandbox Code Playgroud)
这段代码确实有效,但这可能会出错吗?我有人告诉我你不应该使用await这样的高阶函数,所以我只是想问一下这是否有任何问题.
我编写的代码看起来像:
function getStuffDone(param) { | function getStuffDone(param) {
var d = Q.defer(); /* or $q.defer */ | return new Promise(function(resolve, reject) {
// or = new $.Deferred() etc. | // using a promise constructor
myPromiseFn(param+1) | myPromiseFn(param+1)
.then(function(val) { /* or .done */ | .then(function(val) {
d.resolve(val); | resolve(val);
}).catch(function(err) { /* .fail */ | }).catch(function(err) {
d.reject(err); | reject(err);
}); | });
return d.promise; /* or promise() */ | });
} | }
Run Code Online (Sandbox Code Playgroud)
有人告诉我这个被称为" 延迟反模式 "或" Promise构造函数反模式 ",这个代码有什么不好,为什么这被称为 …
我已经开发了几年的JavaScript,我根本不理解有关承诺的大惊小怪.
似乎我所做的只是改变:
api(function(result){
api2(function(result2){
api3(function(result3){
// do work
});
});
});
Run Code Online (Sandbox Code Playgroud)
无论如何,我可以使用像async这样的库,例如:
api().then(function(result){
api2().then(function(result2){
api3().then(function(result3){
// do work
});
});
});
Run Code Online (Sandbox Code Playgroud)
哪个代码更多,可读性更低.我没有在这里获得任何东西,它也不会突然神奇地"平坦".更不用说必须将事物转换为承诺.
那么,这里的承诺有什么大惊小怪?
我在循环中进行多个mongoDB查询.并且想要将所有结果作为一个数据数组发送.但是当我简单地使用return来发送数据时,它只返回undefined而不等待所有数据库请求的结果.我也尝试过使用q.moulde但同样的问题.
码:
var getPrayerInCat = function(data){
var result ;
var finalData = [];
if(data.length >0){
data.forEach(function(data2){
var id= data2.id;
Prayer.find({prayerCat:id},function(err,prayer){
var deferred = Q.defer()
if (err) { // ...
console.log('An error has occurred');
// res.send(err);
result= finalData = err
} else {
if(!prayer){
// console.log(data2.id+'--0');
data2.prayersCount = 0;
result = deferred.resolve(finalData.push(data2))
} else {
// console.log(data2.id+'--'+prayer.length);
data2.prayersCount = prayer.length;
// console.log(prayer)
result = deferred.resolve(finalData.push(data2))
} // else for data forward
}
deferred.promise;
})
// deferred.resolve(finalData);
})
/*if(finalData.length > 0) { …Run Code Online (Sandbox Code Playgroud) 我的节点项目当前包含一个嵌套的回调圣诞树,以便获取数据并按正确的顺序处理它们.现在我正在尝试使用Promises重构,但我不确定如何正确地执行它.
假设我正在提取办公室列表,然后为每个办公室提供所有员工,然后是每个员工的工资.最后,所有实体(办公室,员工和工资)应链接在一起并存储在数据库中.
一些伪代码说明了我当前的代码(省略了错误处理):
fetch(officesEndpoint, function (data, response) {
parse(data, function (err, offices) {
offices.forEach(function (office) {
save(office);
fetch(employeesEndPoint, function (data, response) {
parse(data, function (err, employees) {
// link each employee to office
save(office);
save(employee);
employees.forEach(function () {
fetch(salaryEndpoint, function (data, response) {
parse(data, function (err, salaries) {
// link salary to employee
save(employee);
});
});
});
});
});
});
});
});
Run Code Online (Sandbox Code Playgroud)
我尝试用承诺解决这个问题,但我有几个问题:
saveEmployees职能中,我只能访问员工,而不是办公室中的其他办公室:var restClient = require('node-rest-client');
var client = new restClient.Client();
var xml2js = require('xml2js'); …Run Code Online (Sandbox Code Playgroud) 我有一个api调用,有时会返回分页的响应。我想自动将这些添加到我的诺言中,以便在所有数据到达后获取回调。
这是我的尝试。我希望添加新的承诺,并在完成后解决Promise.all。
实际发生的是Promise.all不等待第二个请求。我的猜测是Promise.all在调用时会附加“侦听器”。
有没有办法“重新初始化” Promise.all()?
function testCase (urls, callback) {
var promises = [];
$.each(urls, function (k, v) {
promises.push(new Promise(function(resolve, reject) {
$.get(v, function(response) {
if (response.meta && response.meta.next) {
promises.push(new Promise(function (resolve, reject) {
$.get(v + '&offset=' + response.meta.next, function (response) {
resolve(response);
});
}));
}
resolve(response);
}).fail(function(e) {reject(e)});
}));
});
Promise.all(promises).then(function (data) {
var response = {resource: []};
$.each(data, function (i, v) {
response.resource = response.resource.concat(v.resource);
});
callback(response);
}).catch(function (e) {
console.log(e);
});
}
Run Code Online (Sandbox Code Playgroud)
所需的流程类似于:
我试图等待一堆承诺完成。我知道我可以用 来做到这一点Promise.all,但是当这些承诺之一将新承诺推入承诺列表时,我不知道该怎么做。
例子:
asyncFunction(...).then(result => {
// do something
});
asyncFunction(...).then(result => {
for(let row of result) {
asyncFunction(row);
}
});
console.log(promises.length); // 2
await Promise.all(promises);
console.log(promises.length); // 5
Run Code Online (Sandbox Code Playgroud)
哪里asyncFunction是这样的:
const asyncFunction = (...args) => {
let result = new Promise((resolve, reject) => {
pool.query(...args, (err, rows, fields) => {
if (err) {
reject(err);
} else {
resolve(rows);
}
});
});
promises.push(result);
return result;
};
Run Code Online (Sandbox Code Playgroud)
这里发生的事情是,前两次调用asyncFunction将 promise 推送到我的promises数组中,promises.length2 也是如此。但是,在等待它们完成之后,第二个调用在Promise.all …
javascript ×7
promise ×6
es6-promise ×3
node.js ×3
q ×3
async-await ×2
bluebird ×2
callback ×1
ecmascript-6 ×1
mongodb ×1