js函数的执行结果是异步返回的,如何避免调用的时候 返回undefined

发布于 2022-09-04 23:45:53 字数 1314 浏览 32 评论 0

想让compress返回压缩后的base64 字符串

但是compress里面 有个异步的onload , 压缩后的字符是异步返回的

如何让var str = compress(xx,xx,xx) 不返回undefined

注:

除了给compress()方法加一个回调函数,还有其他方法吗?

      /**
       * 压缩base64图片
       * @param  {String} base64  图片字符串
       * @param  {Number} quality 压缩品质 0-1
       * @param  {Number} scale   缩放比例       
       * @return {String}         压缩后的base64字符串
       */
      var compress = function(base64, quality, scale) {
        var $img = $('<img/>').prop('src', base64);
        $img[0].onload = function() {
          var dataUrl;
          var width = $img[0].width;
          var height = $img[0].height;
          var canvas = document.createElement('canvas');
          var context = canvas.getContext('2d');

          canvas.width = width * scale;
          canvas.height = height * scale;

          var sx = 0;
          var sy = 0;
          var sWidth = width;
          var sHeight = height;
          var dx = 0;
          var dy = 0;
          var dWidth = width * scale;
          var dHeight = height * scale;
          context.drawImage($img[0], sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
          dataUrl = canvas.toDataURL('image/jpeg', quality); //品质0-1
          return dataUrl;
        }
      };

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风吹雨成花 2022-09-11 23:45:53

既然你使用了 jQuery,那就用 jQuery 的 Deferred。

如果是 ES2015 可以用原生 Promise。另外也可以用其它 Promise 库……这些都是后话

/**
 * 压缩base64图片
 * @param  {String} base64  图片字符串
 * @param  {Number} quality 压缩品质 0-1
 * @param  {Number} scale   缩放比例       
 * @return {String}         压缩后的base64字符串
 */
var compress = function(base64, quality, scale) {
    var $img = $("<img/>").prop("src", base64);

    var deferred = $.Deferred();
    $img[0].onload = function() {
        var dataUrl;
        var width = $img[0].width;
        var height = $img[0].height;
        var canvas = document.createElement("canvas");
        var context = canvas.getContext("2d");

        canvas.width = width * scale;
        canvas.height = height * scale;

        var sx = 0;
        var sy = 0;
        var sWidth = width;
        var sHeight = height;
        var dx = 0;
        var dy = 0;
        var dWidth = width * scale;
        var dHeight = height * scale;
        context.drawImage($img[0], sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
        dataUrl = canvas.toDataURL("image/jpeg", quality); //品质0-1

        deferred.resolve(dataUrl);
        return dataUrl;
    };
    return deferred.promise();
};

使用,用返回的 promise 的 done(callback)then(callback),区别在于 done 可以对同一个 promise 对象多次使用,resolve 的时候依次触发。then() 会返回一个新的 promise。

compress.done(function(dataUrl) {
    console.log(dataUrl);
});
compress.then(function(dataUrl) {
    console.log(dataUrl);
});

如果可以用 ES2017 的话,还可以用 async/await

参考:

素罗衫 2022-09-11 23:45:53

用Promise在onload事件里面resolve可以吗?

心房敞 2022-09-11 23:45:53

除了回调,只能写在onload函数里面,异步就是这样;

觉得代码行多的话在onload里面调用一个函数,函数另外写就好了

节枝 2022-09-11 23:45:53

早就不要用回调了。

Promise,generator, async/await 都可以解决。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文