对象迭代和回调中的 Async/Await 函数

Async/Await Function inside Object iteration and Callback

提问人:achip Baba 提问时间:11/9/2023 最后编辑:mr rogersachip Baba 更新时间:11/9/2023 访问量:53

问:

我的对象如下

let obj = [
  {
    "id": "hlahl2c",
    "name": "Media(video) 1",
    "type": "video",
    "placement": {
      "x": 0,
      "y": 0,
      "width": 617.2537313432834,
      "height": 558.7462686567162,
      "rotation": 0,
      "scaleX": 1,
      "scaleY": 1
    },
    "timeFrame": {
      "start": 0,
      "end": 2001.9999999999998
    },
    "properties": {
      "elementId": "video-hlahl2c",
      "src": "blob:http://localhost:3000/68d041d2-0eef-4bf1-ae3b-fd25af555fcd",
      "effect": {
        "type": "none"
      },
      "imageObject": {
        "type": "coverVideo",
        "version": "5.3.0",
        "originX": "left",
        "originY": "top",
        "left": 0,
        "top": 0,
        "width": 617.25,
        "height": 558.75,
        "fill": "rgb(0,0,0)",
        "stroke": null,
        "strokeWidth": 0,
        "strokeDashArray": null,
        "strokeLineCap": "butt",
        "strokeDashOffset": 0,
        "strokeLineJoin": "miter",
        "strokeUniform": false,
        "strokeMiterLimit": 4,
        "scaleX": 1,
        "scaleY": 1,
        "angle": 0,
        "flipX": false,
        "flipY": false,
        "opacity": 1,
        "shadow": null,
        "visible": true,
        "backgroundColor": "",
        "fillRule": "nonzero",
        "paintFirst": "fill",
        "globalCompositeOperation": "source-over",
        "skewX": 0,
        "skewY": 0,
        "cropX": 0,
        "cropY": 0,
        "src": "blob:http://localhost:3000/68d041d2-0eef-4bf1-ae3b-fd25af555fcd",
        "crossOrigin": null,
        "filters": []
      }
    },
    "fabricObject": {
      "type": "coverVideo",
      "version": "5.3.0",
      "originX": "left",
      "originY": "top",
      "left": 0,
      "top": 0,
      "width": 617.25,
      "height": 558.75,
      "fill": "rgb(0,0,0)",
      "stroke": null,
      "strokeWidth": 0,
      "strokeDashArray": null,
      "strokeLineCap": "butt",
      "strokeDashOffset": 0,
      "strokeLineJoin": "miter",
      "strokeUniform": false,
      "strokeMiterLimit": 4,
      "scaleX": 1,
      "scaleY": 1,
      "angle": 0,
      "flipX": false,
      "flipY": false,
      "opacity": 1,
      "shadow": null,
      "visible": true,
      "backgroundColor": "",
      "fillRule": "nonzero",
      "paintFirst": "fill",
      "globalCompositeOperation": "source-over",
      "skewX": 0,
      "skewY": 0,
      "cropX": 0,
      "cropY": 0,
      "src": "blob:http://localhost:3000/68d041d2-0eef-4bf1-ae3b-fd25af555fcd",
      "crossOrigin": null,
      "filters": []
    }
  }
]

如您所见,src 位于 bloburl 中,因此在发送到服务器之前,我喜欢将所有源转换为 base64 strng ,为此,我需要一个 async/await 函数将该 src 从 blob url 转换为 base64。

首先我使用一个函数对所有 src 键进行深度搜索,然后计划使用回调 functon 来转换该 bloburl ,但该回调 functon 需要是 async/await ,但函数未按预期工作,为了进行深度搜索,我使用了以下 functon

const deepReplace = (obj, keyName, replacer) => {
    for (const key in obj) {
        if (key === keyName) {
            obj[key] = replacer(obj[key]);
        } else if (Array.isArray(obj[key])) {
            (obj[key] ).forEach(member => deepReplace(member, keyName, replacer));
        } else if (typeof obj[key] === "object") {
            deepReplace(obj[key], keyName, replacer);
        }
    }
};

对于回调,这是以下虚拟函数

replace_value_func=(value)=>{
  return value+" someword appended"
}

当我调用时,只要replace_value_func同步,一切都按预期进行,但我需要异步使用 replace_value_func,因为通过该函数我需要将 bloburl 转换为 base64 ,但是当我使用异步replace_value_func它只是返回空对象。如何在循环中使用异步函数作为回调函数?deepReplace(obj,'src',replace_value_func)

使用异步函数基于键搜索和替换嵌套对象值

当我使用 Async/Await 时,我使用以下

const deepReplace = async(obj, keyName, replacer) => {
    for (const key in obj) {
        if (key === keyName) {
            obj[key] = await replacer(obj[key]);
        } else if (Array.isArray(obj[key])) {
            (obj[key] ).forEach(member => deepReplace(member, keyName, replacer));
        } else if (typeof obj[key] === "object") {
            deepReplace(obj[key], keyName, replacer);
        }
    }
};

replace_value_func_with_promise = (value)=>{
  return new Promise(resolve => {
     res="something"+value
   resolve(res)
    });      
}

deepReplace(Obj,'src',replace_value_func_with_promise)

但是上面的代码不起作用

JavaScript 对象 async-await promise 回调

评论

0赞 slebetman 11/9/2023
停止使用 .Javascript 现在对数组迭代有更好的语法:.forEach()for .. of
0赞 achip Baba 11/9/2023
目前更改为 else if (Array.isArray(obj[key])) { for (obj[key])) { deepReplace(member, keyName); } for Each 部分并具有相同的结果,代码只是忽略 await 部分并输入原始值而不是 await

答:

0赞 traktor 11/9/2023 #1
  1. 声明为异步函数。deepReplace
  2. 在没有特殊预防措施的情况下,请勿在异步函数中使用。请改用标准 或(如果适用)循环。.forEachforfor...offor.. in
  3. await潜在的异步结果
  4. 在同步调用代码中,对返回的 promise 进行以 或 use 和子句为前缀的调用。deepReplacerawait.then.catch

请注意,您永远无法在从函数返回后立即获得异步操作的结果 - 它们返回值的承诺,而不是稍后获得的值。async

评论

0赞 traktor 11/9/2023
请不要接受或投票这个答案 - 评论太长了。该帖子可能很快就会被提名为重复职位。
0赞 achip Baba 11/9/2023
我已经更新了 OP,正如您看到的 async/await 我使用了 async 和 await,但该代码不起作用
0赞 traktor 11/9/2023
1. 将原始值解析为原始值。请参阅文档。因此不需要。2. 递归调用,从内部需要他们。3. 帖子中仍然包含一个循环,该循环在同步循环中调用参数函数,无需等待。请勿使用 .4. 避免在 SO 上使用“不起作用”一词。:-)awaitawaitreplace_value_func_with_promisedeepReplacerdeepReplacerawaitdeepReplacer.forEachforEach