【发布时间】:2021-02-06 01:43:40
【问题描述】:
编辑: 目前我认为问题在于 forEach 不知道承诺。 https://zellwk.com/blog/async-await-in-loops/
我正在尝试应用一个节点 javascript 翻译函数(我把它放在帖子的末尾,因为它很长)来循环一个值数组。但是,当我出于某种原因循环时,我只会在循环完成后出现循环函数的某些部分:请允许我说得更清楚:
array = [["hello", "hello" ],
["my", "my", ],
["name", "name" ],
["is", "my" ],
["joe", "joe"]]
function process (item,index){
const translate = require('@vitalets/google-translate-api');
console.log('loopaction'); //this shows that the loop is executing
translate(item[0], {to: 'sp'}).then(result => {
console.log(result.text);
}).catch(err => {
console.error(err);
})
array.forEach(process); // Applying the function process to the array in a ForEach loop
我从中得到了
循环动作 循环动作 循环动作 循环动作 循环动作
你好 米 名词 es 乔
所以似乎 forEach 循环在允许显示值之前完成。这是我真的不明白的,因为数组值被正确翻译,然后以正确的顺序注销。就好像它们被存储在记忆中以备后用。然后在 forEach 循环顺序结束时调用。
翻译函数如下所示:
function translate(text, opts, gotopts) {
opts = opts || {};
gotopts = gotopts || {};
var e;
[opts.from, opts.to].forEach(function (lang) {
if (lang && !languages.isSupported(lang)) {
e = new Error();
e.code = 400;
e.message = 'The language \'' + lang + '\' is not supported';
}
});
if (e) {
return new Promise(function (resolve, reject) {
reject(e);
});
}
opts.from = opts.from || 'auto';
opts.to = opts.to || 'en';
opts.tld = opts.tld || 'com';
opts.from = languages.getCode(opts.from);
opts.to = languages.getCode(opts.to);
var url = 'https://translate.google.' + opts.tld;
return got(url, gotopts).then(function (res) {
var data = {
'rpcids': 'MkEWBc',
'f.sid': extract('FdrFJe', res),
'bl': extract('cfb2h', res),
'hl': 'en-US',
'soc-app': 1,
'soc-platform': 1,
'soc-device': 1,
'_reqid': Math.floor(1000 + (Math.random() * 9000)),
'rt': 'c'
};
return data;
}).then(function (data) {
url = url + '/_/TranslateWebserverUi/data/batchexecute?' + querystring.stringify(data);
gotopts.body = 'f.req=' + encodeURIComponent(JSON.stringify([[['MkEWBc', JSON.stringify([[text, opts.from, opts.to, true], [null]]), null, 'generic']]])) + '&';
gotopts.headers['content-type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
return got.post(url, gotopts).then(function (res) {
var json = res.body.slice(6);
var length = '';
var result = {
text: '',
pronunciation: '',
from: {
language: {
didYouMean: false,
iso: ''
},
text: {
autoCorrected: false,
value: '',
didYouMean: false
}
},
raw: ''
};
try {
length = /^\d+/.exec(json)[0];
json = JSON.parse(json.slice(length.length, parseInt(length, 10) + length.length));
json = JSON.parse(json[0][2]);
result.raw = json;
} catch (e) {
return result;
}
if (json[1][0][0][5] === undefined) {
// translation not found, could be a hyperlink?
result.text = json[1][0][0][0];
} else {
json[1][0][0][5].forEach(function (obj) {
if (obj[0]) {
result.text += obj[0];
}
});
}
result.pronunciation = json[1][0][0][1];
// From language
if (json[0] && json[0][1] && json[0][1][1]) {
result.from.language.didYouMean = true;
result.from.language.iso = json[0][1][1][0];
} else if (json[1][3] === 'auto') {
result.from.language.iso = json[2];
} else {
result.from.language.iso = json[1][3];
}
// Did you mean & autocorrect
if (json[0] && json[0][1] && json[0][1][0]) {
var str = json[0][1][0][0][1];
str = str.replace(/<b>(<i>)?/g, '[');
str = str.replace(/(<\/i>)?<\/b>/g, ']');
result.from.text.value = str;
if (json[0][1][0][2] === 1) {
result.from.text.autoCorrected = true;
} else {
result.from.text.didYouMean = true;
}
}
return result;
}).catch(function (err) {
err.message += `\nUrl: ${url}`;
if (err.statusCode !== undefined && err.statusCode !== 200) {
err.code = 'BAD_REQUEST';
} else {
err.code = 'BAD_NETWORK';
}
throw err;
});
});
}
我意识到有一种承诺格式,我遇到的问题可能与函数的异步性以及承诺需要多长时间才能得到解决有关。我似乎无法弄清楚为什么在我的 forEach 函数完全循环后承诺没有解决或显示,但它似乎以正确的顺序正确保存。很奇怪。
关于导致这种情况发生的函数 translate() 的任何想法?无论如何我可以重写我的函数 process () 以确保 translate 函数解析 promise 并且函数 process () 中的 .then() 在继续之前完全执行?
【问题讨论】:
标签: javascript node.js foreach promise