为了账号安全,请及时绑定邮箱和手机立即绑定

等待函数回调时出现问题

等待函数回调时出现问题

慕神8447489 2023-09-21 16:24:43
我有一个函数向服务器发送消息以获取答案,如果答案为真,我希望我的应用程序向用户发送错误。问题是我无法在我编写的 Fetch 函数中等待回调。这是将问题发送到服务器的功能。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+"&action="+action;    let post="";    let formData=new FormData();    for(let k in data) formData.append(k,data[k]);    for(let k in data) post+="&"+k+"="+encodeURIComponent(data[k]).replace(/%20/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)}}这是我等待第一个函数 donglePaired 的主要代码,如果 donglePaired 返回 true,我会向用户发送错误。let donglePaired = await this.props.app.donglePaired();    if (donglePaired) return this.props.app.setError("ERR_DONGLE");问题是程序不等待 donglePaired,尽管有等待
查看完整描述

4 回答

?
隔江千里

TA贡献1906条经验 获得超10个赞

您可以Promise.race()使用超时函数返回一个。


fetch(action, data, cb) {

  let url = Config.URL + "?version=" + Config.VERSION + "&action=" + action;

  let post = "";

  let formData = new FormData();

  for (let k in data) formData.append(k, data[k]);

  for (let k in data)

    post += "&" + k + "=" + encodeURIComponent(data[k]).replace(/%20/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 result;

      }),

    sleep(Config.HTTP_TIMEOUT * 1000)

  ]);

}


const sleep = ms => new Promise((_, rej) => setTimeout(rej("TIMEOUT"), ms));

它要么返回值,要么拒绝TIMEOUT,或者拒绝 fetch 的错误


然后看起来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);

    }

  }

}


查看完整回答
反对 回复 2023-09-21
?
月关宝盒

TA贡献1772条经验 获得超5个赞

这些片段应该让您了解如何等待回调


发送至 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

}


查看完整回答
反对 回复 2023-09-21
?
慕森卡

TA贡献1806条经验 获得超8个赞

你这里的代码不合适


let donglePaired = await this.props.app.donglePaired();

if (donglePaired) return this.props.app.setError("ERR_DONGLE");

异步函数无法正常返回值,除非它是 Promise 请参阅下面我的简单演示!


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)

})


查看完整回答
反对 回复 2023-09-21
?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

一种可能性是删除async并将其更改为:


   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

});


查看完整回答
反对 回复 2023-09-21
  • 4 回答
  • 0 关注
  • 88 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信