我正在阅读airbnb javascript指南。有一个特别的声明,说:
不要使用迭代器。首选JavaScript的高阶函数,而不要使用for-in或for-of等循环。
他们给出上述声明的原因是:
这执行了我们不变的规则。处理返回值的纯函数比副作用更容易推论。
我无法区分给出的两种编码实践:
const numbers = [1, 2, 3, 4, 5];
// bad
let sum = 0;
for (let num of numbers) {
sum += num;
}
sum === 15;
// good
let sum = 0;
numbers.forEach((num) => {
sum += num;
});
sum === 15;
Run Code Online (Sandbox Code Playgroud)
谁能解释,为什么应该forEach优先于常规for循环?真的有什么不同?使用常规药有副作用iterators吗?
我有一个多forEach循环的函数:
async insertKpbDocument(jsonFile) {
jsonFile.doc.annotations.forEach((annotation) => {
annotation.entities.forEach(async (entity) => {
await this.addVertex(entity);
});
annotation.relations.forEach(async (relation) => {
await this.addRelation(relation);
});
});
return jsonFile;
}
Run Code Online (Sandbox Code Playgroud)
我需要确保forEach调用该this.addVertex函数的循环中的异步代码在执行下一个函数之前已经完成.
但是当我记录变量时,似乎this.addRelation在第一个循环真正结束之前调用了该函数.
所以我尝试await在每个循环之前添加术语,如下所示:
await jsonFile.doc.annotations.forEach(async (annotation) => {
await annotation.entities.forEach(async (entity) => {
await this.addVertex(entity);
});
await annotation.relations.forEach(async (relation) => {
await this.addRelation(relation);
});
});
Run Code Online (Sandbox Code Playgroud)
但同样的行为.
也许是日志函数有延迟?有任何想法吗?
我正在尝试使用包含500多个文档的集合中timestamp的Firestoreadmin时间戳更新字段。
const batch = db.batch();
const serverTimestamp = admin.firestore.FieldValue.serverTimestamp();
db
.collection('My Collection')
.get()
.then((docs) => {
serverTimestamp,
}, {
merge: true,
})
.then(() => res.send('All docs updated'))
.catch(console.error);
Run Code Online (Sandbox Code Playgroud)
这引发一个错误
{ Error: 3 INVALID_ARGUMENT: cannot write more than 500 entities in a single call
at Object.exports.createStatusError (C:\Users\Growthfile\Desktop\cf-test\functions\node_modules\grpc\src\common.js:87:15)
at Object.onReceiveStatus (C:\Users\Growthfile\Desktop\cf-test\functions\node_modules\grpc\src\client_interceptors.js:1188:28)
at InterceptingListener._callNext (C:\Users\Growthfile\Desktop\cf-test\functions\node_modules\grpc\src\client_interceptors.js:564:42)
at InterceptingListener.onReceiveStatus (C:\Users\Growthfile\Desktop\cf-test\functions\node_modules\grpc\src\client_interceptors.js:614:8)
at callback (C:\Users\Growthfile\Desktop\cf-test\functions\node_modules\grpc\src\client_interceptors.js:841:24)
code: 3,
metadata: Metadata { _internal_repr: {} },
details: 'cannot write more than 500 entities in a single …Run Code Online (Sandbox Code Playgroud) 我是async等待和承诺的初学者.我阅读了一些文章并观看了一些教程视频,但我仍然无法完全理解它.所以我有一个我现在正在处理的代码
}).then(function() {
var responseArray = []
[url1,url2,url3,url4].forEach((url)=>{
makeRequest(url)
}).then((response)=>{
responseArray.push(response)
})
return responseArray
})
Run Code Online (Sandbox Code Playgroud)
因此,如预期的那样,responseArray空的返回.我需要让它等到每个makerequest(url)的所有响应都被推送到responseArray.
这是我的尝试
}).then(function() {
var responseArray = []
[url1,url2,url3,url4].forEach((url)=>{
async makeRequest(url)
}).then((response)=>{
await responseArray.push(response)
})
return responseArray
})
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮我解决这个问题吗?
我想通过调用许多async/await函数返回合并的结果。考虑下面我的(错误的)伪代码
const getRemoteData = async function(uri) {
// get result from remote server via XMLHttpRequest
return result;
}
const finalResult {};
const result1 = getRemoteData('http://…');
result1.forEach(async record => {
// each record has a key for another URI
const result2 = await getRemoteData(record["uri"]);
// result2 has a key for yet another URI
const result3 = await getRemoteData(result2["uri"]);
finalResult[ result2["uri"] ] = result3;
})
console.log(finalResult);
Run Code Online (Sandbox Code Playgroud)
当然,既然console.log(finalResult)被称为前所有的临时电话forEach回路已经完成了,finalResult是空的。处理完所有条目finalResult 后如何返回result1?我使用的是最新版本 …
我有一个将数据写入 mongodb 的函数,如下所示:
const writeToDB = async (db, data) => {
const dataKeys = Object.keys(data)
dataKeys.forEach(async key => db.collection(key).insertMany(data[key]))
}
Run Code Online (Sandbox Code Playgroud)
如果我在节点脚本中运行它,效果很好。但是当我尝试在 Jest 中使用它时,beforeAll我从 Jest 中得到了这个异步错误:
测试运行完成后,Jest 一秒钟都没有退出。这通常意味着测试中存在未停止的异步操作。
经过一些故障排除后,我发现这forEach是造成问题的原因。使用for循环解决了这个问题:
const writeToDB = async (db, data) => {
const dataKeys = Object.keys(data)
for (const key of dataKeys) {
await db.collection(key).insertMany(data[key])
}
}
Run Code Online (Sandbox Code Playgroud)
搜索这个问题我遇到了这篇文章: https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404
那里的解释很有道理,但它给我留下了一些疑问:
编辑
读完所有评论后,我意识到我的第一个问题有点无稽之谈。通常我将异步函数的结果分配给变量,如果我不放置等待,则会出现未定义的错误。但这里的情况并非如此,因此脚本正常退出,并且数据库写入在后台同时发生。
我试图在forEach循环中使用带有回调的函数。
在继续下一步之前,我需要等待执行完成。
这是我的代码:
const arr = '6,7,7,8,8,5,3,5,1'
const id = arr.split(',');
const length = id.length;
id.forEach( (x, index) => {
(function FnWithCallback () {
setTimeout(() => { console.log(x) }, 5000);
})();
});
console.log('done');
Run Code Online (Sandbox Code Playgroud)
我想出了一个办法:
const arr = '6,7,7,8,8,5,3,5,1'
const id = arr.split(',');
const length = id.length;
const fn = () => {
return new Promise (resolve => {
id.forEach( (id, index) => {
setTimeout(() => {console.log(id)}, 3000);
if(index === (length - 1))
resolve();
})
})
}
fn().then(()=> { …Run Code Online (Sandbox Code Playgroud) 我想让Puppeteer根据名为 的数组中的项目数单击一些选项卡tabs:
;(async () => {
const browser = await puppeteer.launch({
headless: true
})
const page = await browser.newPage()
await page.goto(`https://www.example.com`)
const tabs = ['tab1', 'tab2', 'tab3']
tabs.forEach((tab, index) => {
await page.click(`.postab-container li:nth-of-type(${ index + 1 }) a`)
})
})()
Run Code Online (Sandbox Code Playgroud)
但我收到这个错误:
Run Code Online (Sandbox Code Playgroud)await page.click(`.postab-container li:nth-of-type(${ index + 1 }) a`) ^^^^ SyntaxError: Unexpected identifier
看来这个forEach声明是混乱的page。
这样做的正确方法是什么?
我有一个对象数组。我需要将它转换为 .jsonl 格式并使用 lambda 函数中的节点将其作为响应发送我一直试图将其更改为字符串并添加 '\n' 以使其成为新行,但它不起作用
import firebase from "@/firebase";
import {
getStorage,
ref,
uploadBytes,
getDownloadURL,
updateDoc,
} from "firebase/storage";
export default {
data() {
return {
imagesUrl: [],
};
},
methods: {
chooseFile() {
document.getElementById("imgUpload").click();
},
uploadImage(e) {
this.files.push(e.target.files[0]);
this.images.push(URL.createObjetURL(this.files));
},
createCity: async function () {
const docRef = firebase.addDoc(
firebase.collection(firebase.firestoreDB, "cities"),
{
name: "Tokyo",
country: "Japan",
}
);
var photos = [];
for (var i = 0; i < this.files.length; i++) {
// files.values contains all the files objects …Run Code Online (Sandbox Code Playgroud) javascript google-cloud-storage firebase vue.js google-cloud-firestore
javascript ×8
node.js ×4
async-await ×3
firebase ×2
foreach ×2
promise ×2
ecmascript-6 ×1
es6-promise ×1
for-loop ×1
jestjs ×1
lambda ×1
puppeteer ×1
typescript ×1
vue.js ×1