繁体   English   中英

如何等待第三方JavaScript函数返回

[英]How to wait for 3rd party JavaScript function to return

给出以下代码段

var empowerInstance = null;

function onClick_btnSendMessage() {
    var childIFrame = window.document.getElementById("editorFrame");
    if (!empowerInstance) {
        empowerInstance = EditorAPI.getInstance(childIFrame.contentWindow, window.location.origin);
    }
    empowerInstance.document.hasChanged(hasChangedCallback);
}

function hasChangedCallback(returnValue) {
    console.log("empowerInstance.document.hasChanged = " + returnValue.isDirty);
    if (returnValue.success === true && returnValue.isDirty === true) {
        empowerInstance.document.save(saveCallback);
    }
}

function saveCallback(returnValue) {
    console.log("empowerInstance.document.save = " + returnValue.success);
    if (returnValue.success === false) {
        console.log(returnValue.message);
    }
}

window.addEventListener("DOMContentLoaded", function (event) {
    console.log("DOM fully loaded and parsed");
    if (typeof location.origin === "undefined")
        window.location.origin = window.location.protocol + "//" + window.location.host;
    document.getElementById("btnSendMessage").addEventListener("click", onClick_btnSendMessage);
});

我不想启动按钮,而是想通过启动Bootstrap选项卡事件来触发代码。

$('a[data-toggle="tab"]').on("shown.bs.tab", function (e) {

    onClick_btnSendMessage(); // Naive way, as this does not wait

    var target = $(e.target).attr("data-EditorUrl"); // activated tab
    var childIFrame = $("#editorFrame");
    childIFrame.attr("src", target);

});

因此,我的问题是“如何在更改childIFrame的源之前等待该功能完成?”。

empowerInstance.document.hasChanged(hasChangedCallback);

我从概念上理解了Promises和Callbacks的用法,但是编写一个功能正确的说法却是另一回事。

更新

对该版本进行了重构,以消除按钮处理程序,从而提高了可读性。

用法也很重要。 首次加载页面时,它位于选项卡上。 该标签与在iFrame中托管的文档相关联。 如果用户编辑此文档,然后尝试更改标签,则我想调用检查是否脏/保存,然后保存后,移至下一个标签/文档。 在某些情况下,选项卡/文档之间的切换不会导致保存,因为文档不脏。

var empowerInstance = null;

function hasChangedCallback(returnValue) {
    console.log("empowerInstance.document.hasChanged = " + returnValue.isDirty);
    if (returnValue.success === true && returnValue.isDirty === true) {
        empowerInstance.document.save(saveCallback);
    }
}

function saveCallback(returnValue) {
    console.log("empowerInstance.document.save = " + returnValue.success);
    if (returnValue.success === false) {
        console.log(returnValue.message);
    }
}

$(function () {

    if (typeof location.origin === "undefined") {
        window.location.origin = window.location.protocol + "//" + window.location.host;
    }

    $('a[data-toggle="tab"]').on("shown.bs.tab", function (e) {

        var childIFrame = $("#editorFrame");
        if (!empowerInstance) {
            empowerInstance = EditorAPI.getInstance(childIFrame[0].contentWindow, window.location.origin);
        }
        empowerInstance.document.hasChanged(hasChangedCallback);// Need to wait for completion 

        var target = $(e.target).attr("data-EditorUrl"); // activated tab
        childIFrame.attr("src", target);

    });
});

谢谢斯蒂芬

您可以使用一些高阶函数来执行所需的操作。 相反,传递的hasChangedCallbacksaveCallback直接向empowerInstance.document方法,你会改为调用返回的回调函数,而且沿着你自己的回调传递,你会打电话一旦所有的异步操作都终于完成了。 外观如下:

$('a[data-toggle="tab"]').on("shown.bs.tab", function (e) {
    var target = $(e.target).attr("data-EditorUrl"); // activated tab

    onClick_btnSendMessage(function () {
        var childIFrame = $("#editorFrame");
        childIFrame.attr("src", target);
    });
});

function onClick_btnSendMessage(myCallback) {
    var childIFrame = window.document.getElementById("editorFrame");
    if (!empowerInstance) {
        empowerInstance = EditorAPI.getInstance(childIFrame.contentWindow, window.location.origin);
    }
    empowerInstance.document.hasChanged(getHasChangedCallback(myCallback));
}

function getHasChangedCallback(myCallback) {
    return function hasChangedCallback(returnValue,  myCallback) {
        console.log("empowerInstance.document.hasChanged = " + returnValue.isDirty);
        if (returnValue.success === true && returnValue.isDirty === true) {
            empowerInstance.document.save(getSaveCallback(myCallback));
        }
    } 
}

function getSaveCallback(myCallback) {
    return function saveCallback(returnValue) {
        console.log("empowerInstance.document.save = " + returnValue.success);
        if (returnValue.success === false) {
            console.log(returnValue.message);
        }

        myCallback && myCallback(); // make sure myCallback isn't null before invoking
    }
}

它并不完全吸引人,但它可以为您带来想要的东西。

我已经重构了您的代码,以展示如何使用Promise做到这一点。

 function onClick_btnSendMessage() { var childIFrame = window.document.getElementById("editorFrame"); if (!empowerInstance) { empowerInstance = EditorAPI.getInstance(childIFrame.contentWindow, window.location.origin); } var doc = empowerInstance.document; return hasChanged(doc).then(function() { return save(doc) }) } function hasChanged(doc) { return new Promise(function(resolve, reject) { doc.hasChanged(function(returnValue) { if (returnValue.success === true && returnValue.isDirty === true) { resolve(returnValue) } else { reject(returnValue) } }) }) } function save(doc) { return new Promise(function(resolve, reject) { doc.save(function(returnValue) { if (returnValue.success === false) { console.log(returnValue.message); reject(returnValue) } else { resolve(returnValue) } }) }) } // ------ $('a[data-toggle="tab"]').on("shown.bs.tab", function(e) { onClick_btnSendMessage().then(function() { var target = $(e.target).attr("data-EditorUrl"); // activated tab var childIFrame = $("#editorFrame"); childIFrame.attr("src", target); }).catch(function(error) { // handle the error console.error('Error!', error) }) }); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM