#javascript #react-native #async-await
#javascript #реагировать -родной #async-ожидание
Вопрос:
У меня есть функция, которая отправляет сообщение на сервер, чтобы получить ответ, и если ответ верен, я хочу, чтобы мое приложение отправило пользователю сообщение об ошибке. Проблема в том, что я не могу дождаться обратного вызова в функции выборки, которую я написал. Это функция, которая отправляет вопрос на сервер.
async donglePaired(){
if (Platform.OS !=='ios'){
var pairedDevices = await BluetoothScanner.getPairedDevices();
console.log('Sending........');
let data={
data:pairedDevices,
};
new Api().fetch("bluetoothCheck",{devices:JSON.stringify(data),userid:this.state.probe.UID},(result) => {
if (!result.err) return false;
console.log("Dongle already paired");
return true;
//logNetworkState
});
}
}
Это функция Api.fetch, которую я написал
fetch(action,data,cb){
let url=Config.URL "?version=" Config.VERSION "amp;action=" action;
let post="";
let formData=new FormData();
for(let k in data) formData.append(k,data[k]);
for(let k in data) post ="amp;" k "=" encodeURIComponent(data[k]).replace(/ /g,' ');
console.log(url post);
console.log(url);
if (data.batch) console.log(data.batch);
let sending=true;
fetch(url,{
method: 'post',
body: formData
})
.then(function(response){
if (true) return response.json();
let txt=response.text();
console.log(txt);
return JSON.parse(txt);
})
.then(
(result)=>{
if (!sending) return;
sending=false;
console.log(JSON.stringify(result));
if (cb) cb(result);
},
(error)=>{
if (!sending) return;
sending=false;
console.log("fetch error");
console.log(error);
if (cb) cb();
}
);
setTimeout(()=>{
console.log("http timeout")
if (!sending) return console.log("nothing to abort");
if (cb) cb();
},Config.HTTP_TIMEOUT*1000)
}
}
И это мой основной код, в котором я жду первого ключа, связанного с функцией, и если ключ, связанный с ключом, возвращает true, я отправляю ошибку пользователю.
let donglePaired = await this.props.app.donglePaired();
if (donglePaired) return this.props.app.setError("ERR_DONGLE");
Проблема в том, что программа не ожидает подключения ключа, несмотря на ожидание
Комментарии:
1. Куда вы добавили
let donglePaired
часть? Это асинхронный метод?2. не могли бы вы добавить журналы, которые вы получаете, по порядку
Ответ №1:
ваш код здесь неуместен
let donglePaired = await this.props.app.donglePaired();
if (donglePaired) return this.props.app.setError("ERR_DONGLE");
Асинхронная функция не может нормально возвращать значение, если оно не является обещанием
Смотрите мою простую демонстрацию ниже!
async function test() {
const result = await asyncRequest()
return result
}
function asyncRequest() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 2000)
})
}
test().then((data) => {
console.log(data)
})
Ответ №2:
Фрагменты должны дать вам представление о том, как ожидать обратного вызова
Отправка в API
async function remove_configuration(filename) {
const data = { filename };
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
};
await fetch('/delete', options);
}
Просто получение данных
async function display() {
let response = await fetch('/get-available-configurations')
let data = await response.json(); // JSON or Text what do you prefer
// do something with data
}
Ответ №3:
Вы могли бы вернуть Promise.race()
функцию с таймаутом.
fetch(action, data, cb) {
let url = Config.URL "?version=" Config.VERSION "amp;action=" action;
let post = "";
let formData = new FormData();
for (let k in data) formData.append(k, data[k]);
for (let k in data)
post = "amp;" k "=" encodeURIComponent(data[k]).replace(/ /g, " ");
console.log(url post);
console.log(url);
if (data.batch) console.log(data.batch);
let sending = true;
return Promise.race([
fetch(url, {
method: "post",
body: formData
})
.then(res => res.json())
.then(result => {
if (!sending) return;
sending = false;
return resu<
}),
sleep(Config.HTTP_TIMEOUT * 1000)
]);
}
const sleep = ms => new Promise((_, rej) => setTimeout(rej("TIMEOUT"), ms));
Он либо возвращает вам значение, либо отклоняет с TIMEOUT
помощью, либо отклоняет с ошибкой из выборки
И donglePaired
тогда выглядит так. Я обернул его с помощью try / catch
async donglePaired() {
if (Platform.OS !== "ios") {
var pairedDevices = await BluetoothScanner.getPairedDevices();
console.log("Sending........");
let data = {
data: pairedDevices
};
try {
let result = await new Api().fetch("bluetoothCheck", {
devices: JSON.stringify(data),
userid: this.state.probe.UID
});
if (!result.err) return false;
console.log("Dongle already paired");
return true;
//logNetworkState
} catch (err) {
console.log(err);
}
}
}
Ответ №4:
Одна из возможностей — удалить async
и изменить его на this:
donglePaired() {
return new Promise( function(resolve, reject) {
if (Platform.OS !=='ios'){
var pairedDevices = await BluetoothScanner.getPairedDevices();
console.log('Sending........');
let data={
data:pairedDevices,
};
new Api().fetch("bluetoothCheck",{devices:JSON.stringify(data),userid:this.state.probe.UID},(result) => {
if (!result.err) reject(false);
console.log("Dongle already paired");
resolve(true);
//logNetworkState
});
}
reject(false);
});
}
И:
this.props.app.donglePaired().then( (response) => {
// do something here, this will only run if the response is true
});