【问题标题】:Pausing javascript async function until user action暂停javascript异步功能,直到用户操作
【发布时间】:2018-01-03 11:40:41
【问题描述】:

我有异步功能,我希望它执行到某个点,暂停执行,并在用户进行某些操作(例如单击按钮)时恢复执行其余功能。我试过这个:

let changed = false;

let promise = new Promise(function(resolve, reject){

    if(changed){

        resolve('success');
    }else{

        reject('failure');
    }
});

async function test(){

    console.log('function started');
    console.log('before await');

    try{

        const fulfilledValue = await promise;
        console.log(fulfilledValue);
    }catch(failure){

        console.log(failure);
    }

    console.log('after await');
};

document.getElementById('change').addEventListener('click', function(){

    if(!changed){

        console.log('changed = true');
        changed = true;
    }else{

        changed = false;
    }
});

test();

但是它并没有像我想的那样工作。异步功能不会等到用户操作。据我了解,这是因为承诺立即被拒绝,因为“已更改”标志最初设置为 false。如何修复此代码以按预期工作?有可能吗?

【问题讨论】:

  • 你不能只完成异步操作,将结果保存在某处,然后仅在单击按钮后显示它吗?这会达到您的预期结果吗?

标签: javascript ecmascript-6 async-await es6-promise


【解决方案1】:

你只需要一种从外部解决你的 Promise 的方法,那么:

let outsideResolve;
let promise = new Promise(function(resolve) {
    outsideResolve = resolve;

});

您现在可以从您的点击处理程序调用 outsideResolve。

【讨论】:

  • 没有。没有理由从外面这样做。
  • 我认为这是一个有用的答案。它提供了另一种可能有用或简化某些情况的方法。
  • 这里是扩展版jsfiddle.net/nvz13gp2/1。请注意,这里的想法是对话框应该是模态的,当它们显示时覆盖页面的其余部分。我没有麻烦在这里添加。
【解决方案2】:

根本不要使用changed 标志。您不能观察变量或等到它具有特定值(轮询除外,但您不希望那样)。相反,您应该简单地从点击处理程序调用 resolve 回调:

var clickPromise = new Promise(function(resolve) {
    document.getElementById('change').addEventListener('click', function(e) {
        resolve(e);
    }, {once: true});
});

【讨论】:

  • once 上的好一个,那么承诺的秘诀就是 .addEventListener('click', resolve, {once: true})。但是由于 once 没有得到很好的支持,所以最好删除一个监听器。
猜你喜欢
  • 2019-01-12
  • 2020-01-18
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多