收藏
回答

调试显示:wx is not defined 能不能帮我把如下代码改成能在云函数里执行的代码?

const request = (params, opts, success, fail, complete) => {


  params = formatParams(params)

  params.Action = firstLetterUpper(params.Action)

  var defaultParams = _buildParams()

  params = Object.assign(defaultParams, params)

  var method = (opts.method || 'GET').toUpperCase()

  var normalized = normalize(params)

  var canonicalized = canonicalize(normalized)

  var stringToSign = `${method}&${encode('/')}&${encode(canonicalized)}`

  const key = 'u92uXpgg0jOuRf3wtd41Df1kxfqwAG' + '&'

  var signature = crypto.HMAC(crypto.SHA1, stringToSign, key, {

    asBase64: true

  })

  normalized.push(['Signature', encode(signature)])

  const url = method === 'POST' ? `${'https://iot.cn-shanghai.aliyuncs.com'}/` : `${'https://iot.cn-shanghai.aliyuncs.com'}/?${canonicalize(normalized)}`

  if (method === 'POST') {

    opts.headers = opts.headers || {};

    opts.headers['content-type'] = 'application/x-www-form-urlencoded'

    opts.data = canonicalize(normalized)

  }

  wx.request({

    url: url,

    data: opts.data ? opts.data : {},

    header: opts.headers,

    method: method,

    dataType: 'json',

    responseType: 'text',

    success: function(res) {

      if (typeof success === 'function')

        success(res)

      else

        console.log("success is not a function")

    },

    fail: function(res) {

      if (typeof fail === 'function')

        fail(res)

      else

        console.log("fail is not a function")

    },

    complete: function(res) {

      if (typeof complete === 'function')

        complete()

      else

        console.log("complete is not a function")

    }

  })

}


以上代码在云函数运行,提示wx is not defined,有没有朋友能帮我把这段代码该成在云函数里可以用的。

多谢!

回答关注问题邀请回答
收藏

2 个回答

  • CRMEB
    CRMEB
    2023-10-17

    在云函数中,wx 对象是不存在的,因此需要将代码中的 wx.request 替换为其他网络请求库。这里我推荐使用 axios 库,首先需要在云函数中安装 axios:


    npm install axios --save
    


    然后修改代码如下:


    const request = (params, opts, success, fail, complete) => {
      params = formatParams(params);
      params.Action = firstLetterUpper(params.Action);
      var defaultParams = _buildParams();
      params = Object.assign(defaultParams, params);
      var method = (opts.method || 'GET').toUpperCase();
      var normalized = normalize(params);
      var canonicalized = canonicalize(normalized);
      var stringToSign = `${method}&${encode('/')}&${encode(canonicalized)}`;
      const key = 'u92uXpgg0jOuRf3wtd41Df1kxfqwAG' + '&';
      var signature = crypto.HMAC(crypto.SHA1, stringToSign, key, {
        asBase64: true
      });
      normalized.push(['Signature', encode(signature)]);
      const url = method === 'POST' ? `${'https://iot.cn-shanghai.aliyuncs.com'}/` : `${'https://iot.cn-shanghai.aliyuncs.com'}/?${canonicalize(normalized)}`;
      if (method === 'POST') {
        opts.headers = opts.headers || {};
        opts.headers['content-type'] = 'application/x-www-form-urlencoded';
        opts.data = canonicalize(normalized);
      }
      // 使用 axios 替换 wx.request
      axios({
        url: url,
        data: opts.data ? opts.data : {},
        headers: opts.headers,
        method: method,
        responseType: 'json',
      })
        .then((res) => {
          if (typeof success === 'function') {
            success(res.data);
          } else {
            console.log("success is not a function");
          }
        })
        .catch((error) => {
          if (typeof fail === 'function') {
            fail(error);
          } else {
            console.log("fail is not a function");
          }
        })
        .finally(() => {
          if (typeof complete === 'function') {
            complete();
          } else {
            console.log("complete is not a function");
          }
        });
    };
    


    这样修改后的代码应该可以在云函数中正常运行了。

    2023-10-17
    有用 1
    回复 4
    • 朱卫华
      朱卫华
      2023-10-20
      多谢,多谢!完美解决!
      2023-10-20
      回复
    • 朱卫华
      朱卫华
      2023-10-20
      好像还是没有同步,代码如下:
      console.log(‘Start’)
                const resultValue = await queryDevicePropertyStatus(‘a1FGCXEvXEE’, list.data[i].deviceid);
                console.log(resultValue)
                console.log(’End‘)


      async function queryDevicePropertyStatus(productKey, deviceName) {
        const aliSdk = require("aliIot-sdk.js");
        aliSdk.request({
          Action: "QueryDevicePropertyStatus",
          ProductKey: "a1FGCXEvXEE",
          DeviceName: deviceName
        }, {
          method: "POST"
        },
        (res) => {
          console.log("Success")
          console.log(res) //查看返回response数据
        },
        (res) => {
          console.log("fail")
        },
        (res) => {
          console.log("complete")
        }
        )
      }


      执行结果如下:


      index.js:70Start
      index.js:71 undefined
      index.js:72 End
      node.js:1 [info] 函数执行成功(耗时 1863ms) undefined
      node.js:1 [info] 调用 本地 云函数 'timer' 完成 (耗时 1866ms)
      index.js:88 Success
      index.js:89 {"Data":{"List":{"PropertyStatusInfo":[{"Identifier":"CURR1","Value":"00000000000000000000":"struct","Unit":"","Name":"地理位置"}]}},"Code":"","Success":true}
      index.js:95 complete




      代码执行时,在Start和End输出之间console.log(resultValue)还是undefined,怎么能等待queryDevicePropertyStatus查询完数据后再执行后面的 console.log(’End‘)程序呢?


      再次感谢!
      2023-10-20
      回复
    • CRMEB
      CRMEB
      2023-10-20回复朱卫华
      要等待queryDevicePropertyStatus查询完数据后再执行后面的console.log(’End‘)程序,你可以使用async/await语法。将console.log(resultValue)放在一个await表达式中,如下所示:
       
      console.log('Start')
      const resultValue = await queryDevicePropertyStatus('a1FGCXEvXEE', list.data[i].deviceid)
      console.log(resultValue)
      console.log('End')
      这样,代码会等待queryDevicePropertyStatus查询完成后再执行console.log(’End‘)。
      2023-10-20
      回复
    • 朱卫华
      朱卫华
      2023-10-20回复CRMEB
      好的,我试试看!多谢您!
      2023-10-20
      回复
  • 朱卫华
    朱卫华
    2023-10-20

    感谢您的回复!

    我采用如下代码可以正确收到服务器返回的数据,

    axios({

        url: url,

      data: opts.data ? opts.data : {},

        header: opts.headers,

        method: 'POST',

        dataType: 'json',

        responseType: 'text'

      }).then(res => {

        console.log(res.data) //可以查询到正确的结果

    }).catch(error => {console.log(error)})

    但是还有两个问题,第一个是服务器返回的数据res.data怎么返回到主函数里呢?

    主函数如下:

    console.log('Start')

              const resultValue = await queryDevicePropertyStatus("a1FGCXEvXEE", list.data[i].deviceid);

              console.log(resultValue)

              console.log('End')


    async function queryDevicePropertyStatus(productKey, deviceName) {

      const aliSdk = require("aliIot-sdk.js");

      aliSdk.request({

        Action: "QueryDevicePropertyStatus",

        ProductKey: "a1FGCXEvXEE",

        DeviceName: deviceName

      }, { method: "POST"})}

    第二个问题是,返回的数据怎么同步,1.651秒后才收到服务器返回数据,但是主函数已经执行完毕了,Start和End之间打印的输出是undefined,调试输出如下:

    [info] 函数被触发,正在执行中...

    index.js:69 Start

    index.js:72 undefined

    index.js:73 End

    node.js:1 [info] 函数执行成功(耗时 1647ms) undefined

    node.js:1 [info] 调用 本地 云函数 'timer' 完成  (耗时 1651ms)

    aliIot-sdk.js:168 {"Data":{"List":{"PropertyStatusInfo":[{"Identifier":"CURR1","Value":"0000000

    再次感谢!


    2023-10-20
    有用
    回复
登录 后发表内容